zoukankan      html  css  js  c++  java
  • webpack2配置

    详细的配置可以参考官网:https://doc.webpack-china.org/guides/

    一开始做项目时都是直接从组里前辈搭建好的脚手架开始写代码,到后来自己写新项目时又是拷贝之前的工程作为脚手架开始。对于脚手架本身却不甚了解,不仅不思考为什么更是没有改进的想法,怪不得工作满一年了却总觉得自己的技术水平在原地踏步,就是没有总结和思考。

    目前组里的技术栈都是使用vue+koa,使用webpack的好处一是方便写vue的单文件组件,二是打包文件方便生产部署再加上能无所顾虑的应用语言的新特性。

    1. 配置文件

    官方文档推荐写webpack配置文件时,先写出一个基本配置文件(base)包含入口、输出等,再根据开发/生产环境所需要插件的不同,利用webpack-merge生成三个配置文件: dev、prod、analyze

    package.json 依赖参考

    "devDependencies": {
        "babel-core": "^6.18.2",
        "babel-loader": "^7.1.1",
        "babel-preset-es2015": "^6.18.0",
        "css-loader": "^0.28.4",
        "koa-webpack-dev-middleware": "^1.4.0",
        "koa-webpack-hot-middleware": "^1.0.3",
        "less": "^2.7.1",
        "less-loader": "^4.0.5",
        "style-loader": "^0.18.2",
        "url-loader": "^0.5.7",
        "vue-loader": "^12.2.2",
        "webpack": "^3.3.0",
        "webpack-bundle-analyzer": "^2.8.3",
        "webpack-dev-middleware": "^1.11.0",
        "webpack-dev-server": "^2.6.1",
        "webpack-hot-middleware": "^2.13.1",
        "webpack-koa-hot-middleware": "^0.1.2",
        "webpack-manifest-plugin": "^1.2.1",
        "webpack-merge": "^4.1.0"
      }

    webpack.config.base.js

     1 'use strict'
     2 let path = require('path');
     3 let webpack = require('webpack');
     4 let WebpackManifestPlugin = require("webpack-manifest-plugin");
     5 
     6 module.exports = {
     7     output: {
     8         path: path.resolve(__dirname, '..', 'build')
     9     },
    10     resolve: {
    11         extensions: ['.js', '.vue'],
    12         modules: ['node_modules'],
    13         alias: {
    14             'leafletCSS': 'leaflet/dist/leaflet.css',
    15             'leaflet$': 'leaflet/dist/leaflet.js',
    16             'vue$': 'vue/dist/vue.min.js',
    17             'vue-resource$': 'vue-resource/dist/vue-resource.min.js'
    18         }
    19     },
    20     module: {
    21         rules: [
    22             {
    23                 test: /.vue$/,
    24                 loader: 'vue-loader',
    25             },
    26             {
    27                 test: /.js$/,
    28                 exclude: /(node_modules|bower_components)/,
    29                 use: {
    30                     loader: 'babel-loader',
    31                     options: {
    32                         presets: ['es2015']
    33                     }
    34                 }
    35             },
    36             {
    37                 test: /.css$/,
    38                 use: [
    39                     'style-loader',
    40                     'css-loader'
    41                 ]
    42             },
    43             {
    44                 test: /.(png|jpe?g|gif|svg|woff2?|ttf|otf)(?.*)?$/,
    45                 loader: 'url-loader',
    46             },
    47             {
    48                 test: /.less$/,
    49                 use: [
    50                     'style-loader',
    51                     'css-loader',
    52                     'less-loader'
    53                 ]
    54             }
    55         ]
    56     },
    57     plugins: [
    58         new WebpackManifestPlugin(),
    59         new webpack.optimize.CommonsChunkPlugin({
    60             name: 'vendor',
    61             minChunks: function (module) {
    62                 // this assumes your vendor imports exist in the node_modules directory
    63                 return module.context && module.context.indexOf('node_modules') !== -1;
    64             }
    65         }),
    66         new webpack.optimize.CommonsChunkPlugin({
    67             name: 'common',
    68             chunks: ['qq', 'navi', 'log', 'guide', 'apply', 'voice', 'pianhang', 'dynamic'], //这里输入需要提取公共代码的entry
    69             minChunks: 2
    70         }),
    71         //CommonChunksPlugin will now extract all the common modules from vendor and main bundles
    72         new webpack.optimize.CommonsChunkPlugin({
    73             name: 'manifest', //But since there are no more common modules between them we end up with just the runtime code included in the manifest file
    74         }),
    75     ]
    76 }

    第16行代码可以参考这里这里,默认NPM包导出的是运行时构建,Vue2的运行时构建不支持单文件组件的template

    第58行的 WebpackManifestPlugin 作用是将输出文件名保存在文件中 (当输出文件名带 chunkhash 时很有用,参考这里)

    第59~74行的 CommonsChunkPlugin 作用是从打包后的 bundle 文件中提取公共模块,将 npm install 的公共模块和业务代码分开,这样浏览器就可以一直缓存公共模块的bundle,参考这里。第一个 CommonsChunkPlugin 作用是将 node_modules 里的模块提取到 vendor.js 里;第二个 CommonsChunkPlugin 作用是将 entry 里的公共代码提取出来放在 common.js 里,参考这里;第三个 CommonsChunkPlugin 作用是将 webpack 运行时代码放在 manifest.js 里

    webpack.config.dev.js

     1 "use strict"
     2 let webpack = require('webpack');
     3 let merge = require('webpack-merge');
     4 let base_config = require('./webpack.config.base');
     5 
     6 module.exports = merge(base_config, {
     7     entry: {
     8         qq: ['./src/qq/qq.js', 'webpack-hot-middleware/client'],
     9         navi: ['./src/navi/navi.js', 'webpack-hot-middleware/client'],
    10         log: ['./src/log/log.js', 'webpack-hot-middleware/client'],
    11         guide: ['./src/guide/guide.js', 'webpack-hot-middleware/client'],
    12         apply: ['./src/apply/apply.js', 'webpack-hot-middleware/client'],
    13         voice: ['./src/voice/voice.js', 'webpack-hot-middleware/client'],
    14         pianhang: ['./src/pianhang/pianhang.js', 'webpack-hot-middleware/client'],
    15         dynamic: ['./src/dynamic/dynamic.js', 'webpack-hot-middleware/client']
    16     },
    17     output: {
    18         filename: '[name].js',
    19     },
    20     devtool: '#eval-source-map',
    21     plugins: [
    22         new webpack.HotModuleReplacementPlugin(),
    23     ]
    24 });

    第 20 行设置source-map,方便用浏览器查看源代码

    webpack.config.prod.js

     1 "use strict"
     2 let webpack = require('webpack');
     3 let merge = require('webpack-merge');
     4 let base_config = require('./webpack.config.base');
     5 
     6 module.exports = merge(base_config, {
     7     entry: {
     8         qq: ['./src/qq/qq.js'],
     9         navi: ['./src/navi/navi.js'],
    10         log: ['./src/log/log.js'],
    11         guide: ['./src/guide/guide.js'],
    12         apply: ['./src/apply/apply.js'],
    13         voice: ['./src/voice/voice.js'],
    14         pianhang: ['./src/pianhang/pianhang.js'],
    15         dynamic: ['./src/dynamic/dynamic.js'],
    16     },
    17     output: {
    18         filename: '[name].[chunkhash].js',
    19     },
    20     plugins: [
    21         new webpack.optimize.UglifyJsPlugin()
    22     ]
    23 });

    第 21 行 UglifyJsPlugin 的作用是压缩、混淆代码

    webpack.config.analyze.js

     1 "use strict"
     2 
     3 let webpack = require('webpack');
     4 let merge = require('webpack-merge');
     5 var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
     6 let prod_config = require('./webpack.config.prod');
     7 
     8 module.exports = merge(prod_config, {
     9     plugins: [
    10         new BundleAnalyzerPlugin()
    11     ]
    12 });

    analyze 文件的作用利用 webpack-bundle-analyzer 插件分析打包情况,

    webpack --config ./config/webpack.config.analyze.js

    运行结果如下:

    webpack的配置文件自定义程度很高,所以在参考他人配置时最好能弄清楚为什么要这样写

    2. webpack-dev-server 

    在开发过程中另一个重要的东西是 webpack-dev-server,它的作用是当你改动源代码后能自动重新打包,再加上 webpack 的HMR-模块热替换特性,这样改动代码就能直接在浏览器里看到效果,省却了代码手动打包+刷新浏览器的步骤。使用 webpack-dev-server 有 CLI 和 API 两种使用方法。

    CLI 方式设置 dev 文件中的 HotModuleReplacementPlugin 和 devServer 启用 HMR。启动的命令为:

    webpack-dev-server --config ./config/webpack.config.dev.js

    API 方式直接在命令里设置参数,如:(这里用到了 Unix Domin Socket,也可以直接指定 ip和端口)

    webpack-dev-server --config config/webpack.dev.config.js --public 0.0.0.0:8056 --progress --inline --hot --socket .dev-shared/sockets/webpack.sock

    webpack-dev-server 的方式配置简单,缺点是引入 bundle 比较麻烦,需要指定其它端口

    3. webpack-dev-middleware 

    上述配置文件就是使用的该方法,需要有 koa-webpack-dev-middleware、koa-webpack-hot-middleware(热更新)。然后在 index.js 里写:

    1 if (process.env.NODE_ENV == 'dev') {
    2     let webpack = require('webpack');
    3     let webpackConfig = require('./config/webpack.config.dev.js');
    4     let webpackDevMiddleware = require('koa-webpack-dev-middleware');
    5     let webpackHotMiddleware = require('koa-webpack-hot-middleware');
    6     let compiler = webpack(webpackConfig);
    7     app.use(webpackDevMiddleware(compiler));
    8     app.use(webpackHotMiddleware(compiler));
    9 }

    这样就不需要通过额外的端口获取 bundle 文件了,注意这里是 koa 环境

    4. 如何在前端框架里引入 bundle

    由于 webpack prod 配置文件里使用了 chunkhash 作为 bundle 的名字的一部分,修改业务代码,chunkhash 会发生改变,所以需要通过一些方法自动将 bundle 名字注入到前端页面里:

    第一种方法是通过在后端 controller 里读取 manifest.json 里的内容,然后通过模板引擎,注入到页面里,例如 nunjucks:

    {% for path in paths %}
        <script src="{{path}}"></script>
    {% endfor %}

    第二种方法是拓展模板引擎命令,例如 xtpl:

    {{{ xScript('manifest.js') }}}
    {{{ xScript('vendor.js') }}}
    {{{ xScript('common.js') }}}
    {{{ xScript('apply.js') }}}

    xtpl 命令拓展示例 xtpl.ext.js :

     1 let xtplApp = require('xtpl/lib/koa');
     2 let xtpl = require('xtpl/lib/xtpl');
     3 let XTemplate = xtpl.XTemplate;
     4 
     5 XTemplate.addCommand('xScript', function(scope, option){
     6     let name = option.params[0];
     7     if (process.env.NODE_ENV !== 'dev') {
     8         let assets_map = require('./manifest');
     9         name = assets_map[name];
    10     }
    11     return '<script src="' + name + '" ></script>';
    12 });
    13 
    14 module.exports = xtplApp;

    然后在 index.js 里

    let xtpl = require('./extensions/xtpl.ext');

    注意引入 bundle 的时候要注意引入顺序:manifest > vendor > common > entry,否则可能会报 ReferenceError: webpackJsonp is not defined 错误,还要注意要有 .babelrc 文件:

    {
        "presets": ["es2015"]
    }

    否则会报 SyntaxError: Unexpected token: name (xxxxxx) from Uglify plugin 之类的错误,无法识别语言新特性

  • 相关阅读:
    668. Kth Smallest Number in Multiplication Table
    658. Find K Closest Elements
    483. Smallest Good Base
    475. Heaters
    454. 4Sum II
    441. Arranging Coins
    436. Find Right Interval
    410. Split Array Largest Sum
    392. Is Subsequence
    378. Kth Smallest Element in a Sorted Matrix
  • 原文地址:https://www.cnblogs.com/cqq626/p/7140979.html
Copyright © 2011-2022 走看看