zoukankan      html  css  js  c++  java
  • webpack,配置,上手,例子

    1.webpack是什么?
    2.为什么要用webpack?
    3.怎么用webpack?

    webpack是什么?

    答:webpack是前端模块化应用和开发的打包工具,解决前端模块依赖的工具。打包所有的脚本,图片,css。

    为什么要用webpack?
    答:使用webpack可以让前端开发变得工程化和模块化,方便前端开发,提高开发速率。
    webpack的主要优点是:模块化。
    缺点是配置繁琐。

    怎么使用webpack?
    答:参考官网文档:https://webpack.js.org/concepts/
    或者中文文档:https://www.webpackjs.com/concepts/
    看完后还不知道怎么用?请看我的使用例子。


    本例中使用webpack的目的:
    1.前端开发独立于后端使用webpack-dev-server,将页面可在本地查看,webpack-dev-server中的proxy,代理后端借口
    2.用webpack的loader解析.vue后缀的文件
    3.配置webpack的热更新,使得修改前端代码,页面自动更新
    4.利用webpack-merge区分开发环境的配置和生产环境的配置
    5.自动解析生产页面

    webpack依赖webpack.config文件,生产环境和开发环境对应不用的位置文件,共同的配置文件放在一起

    src 目录

    package.json文件中的配置

      "scripts": {
        "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --config ./webpack_config/webpack.config.development.js",
        "build": "cross-env NODE_ENV=production webpack --progress --hide-modules --config ./webpack_config/webpack.config.production.js"
      },
    

    webpack.config.common.js中的配置

    var path = require('path')
    var webpack = require('webpack')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const ManifestPlugin = require('webpack-manifest-plugin');
    
    var glob = require('glob')
    var files = glob.sync(path.resolve(__dirname, '../src/*/index.js'));
    var newEntries = {};
    const config = {
        entry: {
            vendor: [
                './public/bower_components/jquery/dist/jquery.js',
                './public/bower_components/bootstrap/dist/css/bootstrap.css',
                './public/bower_components/bootstrap/dist/js/bootstrap.js'
            ]
        },
        output: {
            path: path.resolve(__dirname, '../public/vue_dist/'),
            publicPath: '/vue_dist/',
            filename: '[name].js'
        },
        module: {
            rules: [{
                    test: /.css$/,
                    use: [
                        'vue-style-loader',
                        'css-loader'
                    ],
                },
                {
                    test: /.scss$/,
                    use: [
                        'vue-style-loader',
                        'css-loader',
                        'sass-loader'
                    ],
                },
                {
                    test: /.sass$/,
                    use: [
                        'vue-style-loader',
                        'css-loader',
                        'sass-loader?indentedSyntax'
                    ],
                },
                {
                    test: /.vue$/,
                    loader: 'vue-loader',
                    options: {
                        loaders: {
                            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
                            // the "scss" and "sass" values for the lang attribute to the right configs here.
                            // other preprocessors should work out of the box, no loader config like this necessary.
                            'scss': [
                                'vue-style-loader',
                                'css-loader',
                                'sass-loader'
                            ],
                            'sass': [
                                'vue-style-loader',
                                'css-loader',
                                'sass-loader?indentedSyntax'
                            ]
                        }
                        // other vue-loader options go here
                    }
                },
                {
                    test: /.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(?.+)?$/,
                    use: [{
                        loader: 'url-loader',
                        options: {
                            limit: 10000
                        }
                    }]
                },
                {
                    test: path.resolve(__dirname, '../public/bower_components/jquery/dist/jquery.js'),
                    use: [{
                        loader: 'expose-loader',
                        options: 'jQuery'
                    }, {
                        loader: 'expose-loader',
                        options: '$'
                    }]
                }
            ]
        },
        plugins: [
            new ManifestPlugin()
        ],
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.esm.js'
            },
            extensions: ['*', '.js', '.vue', '.json']
        },
        performance: {
            hints: false
        }
    }
    console.log(files + '------------files-------------------------');
    
    files.forEach(function(f) {
        var name = /.*/(.*?/index).js/.exec(f)[1]; //register/main这样的文件名
        console.log(name + '------------name-------------------------');
        newEntries[name] = f;
    });
    console.log(newEntries + '------------newEntries-------------------------');
    
    config.entry = Object.assign({}, config.entry, newEntries);
    
    
    
    module.exports = config;
    

    webpack.config.development.js 配置文件

    const merge = require('webpack-merge');
    const common = require('./webpack.config.common.js');
    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const webpack = require('webpack')
    var glob = require('glob')
    var files = glob.sync(path.resolve(__dirname, '../src/*/index.js'));
    var plugins = [];
    files.forEach(function(f) {
        var name = /.*/(.*?/index).js/.exec(f)[1]; //register/main这样的文件名
        var plug = new HtmlWebpackPlugin({
            filename: path.resolve(__dirname, '../public/vue_dist/' + name + '.html'),
            chunks: ['vendor', name],
            template: path.resolve(__dirname, '../src/index.html'),
            inject: true
        });
        plugins.push(plug);
    });
    plugins.push(
        new webpack.optimize.CommonsChunkPlugin({
            names: ['vendor']
        }));
    module.exports = merge(common, {
        plugins: plugins,
        devtool: '#eval-source-map',
        devServer: {
            historyApiFallback: true,
            noInfo: true,
            overlay: true,
            port: 8080,
            host: 'localhost',
            publicPath:'/vue_dist',
            proxy: [{
                context: ["/upload", "/phone",'/register','/users'],
                target: "http://127.0.0.1:3000",
            }],
            openPage: 'vue_dist/upload/index.html'
        },
        output: {
            path: path.resolve(__dirname, '../public/vue_dist/'),
            publicPath: '/vue_dist',
            filename: '[name].js'
        },
    });
    

    webpack.config.production.js 配置文件

    const merge = require('webpack-merge');
    const common = require('./webpack.config.common.js');
    const path = require('path');
    var webpack = require('webpack')
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    var fillter = ['upload']
    var glob = require('glob')
    var files = glob.sync(path.resolve(__dirname, '../src/*/index.js'));
    var plugins = [];
    files.forEach(function(f) {
        var name = /.*/(.*?/index).js/.exec(f)[1]; //register/main这样的文件名
        var c = false;
        for (let f = 0; f < fillter.length; f++) {
            const element = fillter[f];
            if (name.indexOf(element) > -1) {
                c = true;
                break;
            }
        }
        if (!c) {
            var plug = new HtmlWebpackPlugin({
                filename: path.resolve(__dirname, '../public/vue_dist/' + name + '.html'),
                chunks: [name],
                template: path.resolve(__dirname, '../src/index.html'),
                inject: true
            });
            plugins.push(plug);
        }
    });
    plugins.push(
        new CleanWebpackPlugin(['vue_dist'], {
            // Absolute path to your webpack root folder (paths appended to this)
            // Default: root of your package
            root: path.resolve(__dirname, '../public/'),
    
            // Write logs to console.
            verbose: true,
    
            // Use boolean "true" to test/emulate delete. (will not remove files).
            // Default: false - remove files
            dry: false,
    
            // If true, remove files on recompile. 
            // Default: false
            watch: false,
    
            // Instead of removing whole path recursively,
            // remove all path's content with exclusion of provided immediate children.
            // Good for not removing shared files from build directories.
            exclude: ['files', 'to', 'ignore'],
    
            // allow the plugin to clean folders outside of the webpack root.
            // Default: false - don't allow clean folder outside of the webpack root
            allowExternal: false,
    
            // perform clean just before files are emitted to the output dir
            // Default: false
            beforeEmit: false
        })
    )
    module.exports = merge(common, {
        devtool: '#eval-source-map',
        plugins: plugins
    });
    
    if (process.env.NODE_ENV === 'production') {
        module.exports.devtool = '#source-map'
            // http://vue-loader.vuejs.org/en/workflow/production.html
        module.exports.plugins = (module.exports.plugins || []).concat([
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: '"production"'
                }
            }),
            new webpack.optimize.UglifyJsPlugin({
                sourceMap: true,
                compress: {
                    warnings: false
                }
            }),
            new webpack.LoaderOptionsPlugin({
                minimize: true
            })
        ])
    }
    

    用到的插件:

    CleanWebpackPlugin 删除目录专用

    HtmlWebpackPlugin Plugin that simplifies creation of HTML files to serve your bundles

    webpack-merge 合并webpack.config 文件

    glob 找到匹配的文件

    ManifestPlugin Webpack plugin for generating asset manifests. 生成打包列表like this

    {
    "register/index.js": "/vue_dist/register/index.js",
    "register/index.js.map": "/vue_dist/register/index.js.map",
    "upload/index.js": "/vue_dist/upload/index.js",
    "upload/index.js.map": "/vue_dist/upload/index.js.map",
    "vendor.js": "/vue_dist/vendor.js",
    "vendor.js.map": "/vue_dist/vendor.js.map",
    "element-icons.ttf": "/vue_dist/6f0a76321d30f3c8120915e57f7bd77e.ttf",
    "glyphicons-halflings-regular.woff2": "/vue_dist/448c34a56d699c29117adc64c43affeb.woff2",
    "glyphicons-halflings-regular.woff": "/vue_dist/fa2772327f55d8198301fdb8bcfc8158.woff",
    "glyphicons-halflings-regular.ttf": "/vue_dist/e18bbf611f2a2e43afc071aa2f4e1512.ttf",
    "glyphicons-halflings-regular.svg": "/vue_dist/89889688147bd7575d6327160d64e760.svg",
    "glyphicons-halflings-regular.eot": "/vue_dist/f4769f9bdb7466be65088239c12046d1.eot"
    }

    expose-loader 解决全局变量的问题 like jQuery 和 $ 对应


    webpack 配置总结
    webpack配置目的,自动打包,热加载,快速开发,将需要的部分配置好自动打包

    打包策略

    首先,项目打包策略遵循以下几点原则:

    选择合适的打包粒度,生成的单文件大小不要超过500KB
    充分利用浏览器的并发请求,同时保证并发数不超过6
    尽可能让浏览器命中304,频繁改动的业务代码不要与公共代码打包
    避免加载太多用不到的代码,层级较深的页面进行异步加载
    基于以上原则,我选择的打包策略如下:

    第三方库如vue、jquery、bootstrap打包为一个文件
    公共组件如弹窗、菜单等打包为一个文件
    工具类、项目通用基类打包为一个文件
    各个功能模块打包出自己的入口文件
    各功能模块作用一个SPA,子页面进行异步加载

    webpack配置
    entry 入口文件,多入口。apps/question/index这样的,则会生成对应的目录结构
    output 打包后的出口文件
    plugin 插件
    rules 文件处理
    devserver 开发服务器,可代理接口,方便与后台开发
    .....

    0.约定开发目录结构
    1.多入口,多出口,按需要的文件夹生成打包后的文件 glob
    2.生产环境和开发环境分开配置,webpack-merg


    如有错漏,请多多指教!


  • 相关阅读:
    1592:【例 1】国王
    状态压缩类动态规划笔记
    1300:鸡蛋的硬度
    1263:【例9.7】友好城市
    第四部分-并发编程案例分析4:高性能数据库连接池HikariCP
    容器基础3:容器镜像
    第四部分-并发编程案例分析3:高性能队列Disruptor
    容器基础2:隔离与限制
    第四部分-并发编程案例分析1:限流Guava RateLimiter
    容器基础1:进程
  • 原文地址:https://www.cnblogs.com/ivanlee-ee-233/p/8886915.html
Copyright © 2011-2022 走看看