美文网首页
打包平台Webpack(V3-V4)和Babel(V6-V7)升

打包平台Webpack(V3-V4)和Babel(V6-V7)升

作者: pansly | 来源:发表于2019-04-09 20:32 被阅读0次

    webpack3.X 升级到 4.X

    4.0的发布,让构建速度提升98%,包体积更小,配置,压缩,更现代化。具体请看

    https://doc.webpack-china.org/guides/migrating/#-loader

    • 需要升级nodejs到v6及以上版本(建议升级到10.13.0LTS版本)
    • 如果要使用 webpack cli 命令,则需要单独再安装 webpack-cli

    更新第三方依赖

    这里会遇到很多错误提示,只要把相关的依赖升级到最新版本就好了。happypack的升级是比较容易忽略的,因为错误提示根本看不出来,看了很多网友分享的升级血泪史才发现的。。。

    npm i webpack file-loader happypack less-loader webpack-dev-server webpack-merge -D
    
    

    构建模式 mode: 包括development,production(这个升级方便了许多,官方做了许多默认设置,省去了不少工作)

    参考文档: https://www.jianshu.com/p/80eaede27f37

    module.exports = {
      // ...
      mode: 'production',
    }
    

    或者

    "scripts": {
        "prd": "webpack --config conf/webpack.prd.config.js -mode=production",
    }
    

    默认配置(图中红色部分)

    支持json直接引入,不再需要json-loader,如果是其它json插件,则需要设置 type: 'javascript/auto'

    module.exports = {
      // ...
      rules: [
        {
          test: /config\.json$/,
          loader: 'special-loader',
          type: 'javascript/auto',
          options: {...}
        }
      ]
    };
    

    production 模式默认开启压缩,不再需要设置 uglifyjs-webpack-plugin

    optimization: {
       minimize:true
    }
    

    移除module.loaders(webpack3就被废弃了,现在完全移除了,不再支持)

    module: {
        rules: [{
            test: /\.vue$/,
            loader: 'vue-loader',
            options: vueLoaderConfig(entryFile)
        }]
    }
    

    公共代码提取

    • CommonsChunkPlugin 被移除,使用 optimization.splitChunks替代。
    /*
     * chunks: 表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all;
     * minSize: 表示在压缩前的最小模块大小,默认为0;
     * minChunks: 表示被引用次数,默认为1;
     * maxAsyncRequests: 最大的按需(异步)加载次数,默认为1;
     * maxInitialRequests: 最大的初始化加载次数,默认为1;
     * name: 拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成;
     * cacheGroups: 缓存组。
     */
      optimization: {
        noEmitOnErrors: true,
        splitChunks: {
          chunks: 'all',
          minSize: 0,
          maxInitialRequests: Infinity,
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name(module) {
                let bundleName = '';
                let packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
                packageName = packageName.replace('@', '');
                switch (packageName) {
                  case 'yqb-mint-ui':
                  case 'mint-ui':
                    bundleName = 'mint';
                    break;
                  case 'vue-touch':
                  case 'vue-i18n':
                  case 'dayjs':
                  case 'axios':
                  case 'better-scroll':
                    bundleName = 'lib';
                    break;
                  default:
                    bundleName = 'vendor';
                    break;
                }
                return bundleName;
              }
            }
          }
        }
      },
    
    

    alias

    别名:为了让后续引用的地方减少路径的复杂度。

    pack项目配置 pack-projects-alias

    DefinePlugin

    DefinePlugin 允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和发布模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 DefinePlugin 的用处,设置它,就可以忘记开发和发布构建的规则。

    UglifyJsPlugin

    现在也不需要使用这个plugin了,只需要使用optimization.minimize为true就行,production mode下面自动为true

    mini-css-extract-plugin 替换为 extract-text-webpack-plugin

    由于 extract-text-webpack-plugin 作者表示不再支持webpack4.3.0,未来 extract-text-webpack-plugin 将废弃,作者建议使用 mini-css-extract-plugin 插件.

    [图片上传失败...(image-58a23e-1551018520188)]

    问题1: mini-css-extract-plugin 的使用

    这个需要注意区分开发环境使用vue-style-loader就好

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    // 开发环境使用vue-style-loader,方便热更新调试开发
    rules:[
        {
            test: /\.css$/,
            use: [process.env.NODE_ENV !== 'production'
            ? 'vue-style-loader'
            : MiniCssExtractPlugin.loader,
          'css-loader']
        }
    ]
    

    问题2: 世纪大blocker:将css提取为一个文件

    现状:webpack4默认会将css也分割成多个块,但是大多数情况下css总文件并不大,我们并不需要将css分的太细,有时候只需要一份bundle.css就够了。配置方法:

    config.optimization.splitChunks.cacheGroups.styles = {
        name: 'style',
         // 一开始这里忘了匹配vue文件,总是会生成多个文件,需要注意
        test: /\.(scss|css|less|vue)$/,
        chunks: 'all',
        priority: 30,
        enforce: true
    }
    

    但是设置cacheGroup的同时还会生成style.js文件,这并不是我们需要的,我们期望只生成一份css文件,并且不需要这个多余的js文件,不过无奈。。这个问题依然存在,很多人因为这个问题而放弃了升级webpack4。

    我们同样遇到了这个问题,因为旧插件项目引入的资源都是写死的,如果要引入这个style.js文件的话,改动较大,这是个悲伤的故事。。无法做到无感知升级。

    看webpack说明预计要到webpack5才会解决这个问题。。。

    该问题的相关issue见:

    Single-file configuration emits JS assets in its own chunk group

    [图片上传失败...(image-bb9379-1551018520188)]

    [WIP] Support for webpack 4

    [图片上传失败...(image-a52368-1551018520187)]

    升级体验

    升级后用碧桂园pamo项目打包测试了下打包效果,升级后的js资源包(压缩后)从1.2M降到了300多kb,简直就是amazing了。。。

    不过开发环境的编译速度并没有什么明显的变化。

    今天进一步优化了plugins-consumRecord消费记录模块,并对打包压缩后的js文件做了对比,记录一下

    moment替换成dayjs的变化是很明显的,直接下降了180kb,压缩后的dayjs只有2kb,非常可观,而dayjs也足够满足业务需求。

    external的设置,主要是因为插件项目或者h5项目引入的vue相关资源是从c999文件或者cdn加载,一定程度上减少了打包后的体积。

    externals: {
        zepto: 'Zepto',
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter'
    },
    

    常用的 webpack插件: https://segmentfault.com/a/1190000015355816

    升级到Babel7

    babel 7.X变化 ?

    1. 使用npm的scope包@balbel/xxx

    注释: 什么是scope包?

    https://www.npmjs.com.cn/misc/scope/

    1. 所有阶段预设state-x均已弃用,使用plugin代替
    { "plugins": [ 
    // Stage 0 
    "@babel/plugin-proposal-function-bind", 
    // Stage 1 
    "@babel/plugin-proposal-export-default-from", 
    "@babel/plugin-proposal-logical-assignment-operators", ["@babel/plugin-proposal-optional-chaining", { "loose": false }], ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }], 
    ["@babel/plugin-proposal-nullish-coalescing-operator", { "loose": false }], 
    "@babel/plugin-proposal-do-expressions", 
    // Stage 2 
    ["@babel/plugin-proposal-decorators", { "legacy": true }], //解析装饰器 "@babel/plugin-proposal-function-sent", 
    "@babel/plugin-proposal-export-namespace-from", 
    "@babel/plugin-proposal-numeric-separator", 
    "@babel/plugin-proposal-throw-expressions", // 
    Stage 3 
    "@babel/plugin-syntax-dynamic-import", 
    "@babel/plugin-syntax-import-meta", 
    ["@babel/plugin-proposal-class-properties", { "loose": false }], "@babel/plugin-proposal-json-strings" ] }
    
    1. @babel/polyfill是@babel/runtime-corejs2的别名
    { "presets": [ ["@babel/preset-env", {"useBuiltIns": "usage"}] ], "plugins": [ ["@babel/plugin-transform-runtime",{"corejs": 2}] ] }
    

    我们是如何升级的?

    官方升级指南: https://babeljs.io/docs/en/v7-migration

       "@babel/core": "^7.1.6",
       "@babel/plugin-proposal-class-properties": "^7.1.0",
       "@babel/plugin-proposal-decorators": "^7.1.6",
       "@babel/plugin-transform-runtime": "^7.1.0",
       "@babel/preset-env": "^7.1.6",
       "@babel/runtime": "^7.1.5",
       "@babel/plugin-syntax-dynamic-import": "^7.0.0",
       "babel-plugin-dynamic-import-webpack": "^1.1.0",
       "babel-plugin-import": "^1.11.0",
       "babel-eslint": "^10.0.1",
       "babel-loader": "^8.0.4",
    

    相关文章

      网友评论

          本文标题:打包平台Webpack(V3-V4)和Babel(V6-V7)升

          本文链接:https://www.haomeiwen.com/subject/yxdiyqtx.html