博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何优雅的升级到webpack4
阅读量:6695 次
发布时间:2019-06-25

本文共 6550 字,大约阅读时间需要 21 分钟。

前言

现在距离2018年2月15号webpack4.0.0出来已经有一段时间了,现在已经出了 @vue/cli 3.0,但是楼主还没试过,听说很强大,想要试水的可以看文档 ,官方脚手架都用上webpack4了,你项目还停留在webpack3,甚至webpack2,是不是觉得落伍了。 受号称0配置的parcel启发,webpack4 增加了一些默认配置,摒弃掉了一些难懂的配置,对用户更加友好,下面我来讲一讲比较大的一些变化

环境

不再支持 Node.js 4。

默认出入口

在 Webpack 4 中,不再强制要求指定 entry 和 output 路径。webpack 4 会默认 entry 为 ./src,output 为 ./dist,当然了,这只是开胃菜。

mode 构建模式

webpack 提供了两种构建模式可供选择 development 和 production

选项 描述
development 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin(固化 runtime 内以及在使用动态加载时分离出的 chunk 的 chunk id) 和 NamedModulesPlugin(开启 HMR[热重载]的时候使用该插件会显示模块的相对路径)。
production 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.

也就是说如果 mode 为development 时候官方脚手架可以砍掉的代码

// webpack.development.config.jsmodule.exports = {+ mode: 'development'- plugins: [-   new webpack.NamedModulesPlugin(),-   new webpack.DefinePlugin({-     'process.env': require('../config/dev.env')-   }),- ]}复制代码

如果 mode 为production 时候官方脚手架可以砍掉的代码

// webpack.production.config.jsmodule.exports = {+  mode: 'production',-  plugins: [-    new UglifyJsPlugin(/* ... */),-    new webpack.DefinePlugin({-       'process.env': require('../config/dev.env')-    }),-    new webpack.optimize.ModuleConcatenationPlugin()-  ]}复制代码

import(): 动态导入

在 webpack 4 中,import() 会返回一个带命名空间(namespace)的对象,这对 ES Module 不会有影响,但对于遵循 commonjs 规范的模块则会加一层包裹:

// webpack 2/3import("./commonjs").then(exports => {	// ...})// webpack 4import("./commonjs").then({
default: exports}=> { // ...})复制代码

optimization 配置项

配置项新增了 optimization 选项,智能的根据所选模式mode为做运行优化。

使用这个配置的时候之前的一些插件可以使用 optimization 里的配置代替

  • NoEmitOnErrorsPlugin 替换为 optimization.noEmitOnErrors (默认只在 production 模式)
  • ModuleConcatenationPlugin 替换为 optimization.concatenateModules(默认只在 production 模式)
  • NamedModulesPlugin 替换为 optimization.namedModules(默认只在 develoment 模式) CommonsChunkPlugin 插件被弃用,使用 optimization.splitChunks, optimization.runtimeChunk 代替
// webpack.prod.conf.jsconst config = {   // ...   plugins: [-    new webpack.NoEmitOnErrorsPlugin(),-    new webpack.optimize.ModuleConcatenationPlugin(),    // 预编译-    new webpack.optimize.CommonsChunkPlugin({-      name: 'vendor',-      minChunks (module) {-        // any required modules inside node_modules are extracted to vendor-        return (-          module.resource &&-          /\.js$/.test(module.resource) &&-          module.resource.indexOf(-            path.join(__dirname, '../node_modules')-          ) === 0-        )-      }-    }),-    new webpack.optimize.CommonsChunkPlugin({-      name: 'manifest',-      minChunks: Infinity-    }),   ],+  optimization: {+    noEmitOnErrors: true,+    concatenateModules: true,+    splitChunks: { +       chunks: 'all', +       name: 'common', +    }, +    runtimeChunk: { +        name: 'runtime'+    }+  }};复制代码
// webpack.dev.conf.jsconst config = {   // ...   plugins: [-    new webpack.NamedModulesPlugin()   ]+  optimization: {+    namedModules: true+  }};复制代码

optimization.splitChunks 默认是不用设置的。如果 mode 是 production,那 Webpack 4 就会开启 Code Splitting。默认 Webpack 4 只会对按需加载的代码做分割。如果我们需要配置初始加载的代码也加入到代码分割中,可以设置 splitChunks.chunks 为 'all'

压缩

webpack4 的mode 设置成 production 时,默认开启代码压缩,但是我要敲黑板,划重点了,uglifyjs-webpack-plugin 终于到 v1.0.0 版本了,支持多进程压缩,缓存以及es6语法,无需单独安装转换器。感动不感动。想看的话可以看这里。想要覆盖配置可以这样

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')module.exports = {  // ...  optimization: {    minimizer: [      new UglifyJsPlugin() // 具体配置可看github    ]  }}复制代码

##移除的功能 ## 移除了 module.loaders 移除了 loaderContext.options 移除了 Compilation.notCacheable 移除了 NoErrorsPlugin 移除了 Dependency.isEqualResource 移除了 NewWatchingPlugin 移除了 CommonsChunkPlugin

周边

既然讲了 webpack 做了比较大的更新,周边的配套设施也不要不舍得,改换久换,由于我平时项目中使用vue,如果你也使用vue的话,那么针对vue的有几个变化你要知道:

vue-loader

什么?学不动了,只要用官网的脚手架不就好了?前端的知识不断更新,固步自封,只会不进则退。但是你要相信,webpack也好,vue-loader 也好,api 会越来越好懂,性能也会更加高效,所以,扶我起来,我还能学。。。

Vue Loader v15 使用了一个不一样的策略来推导语言块使用的 loader。 在 v14 或更低版本中,如果你想为一个推导出来的 loader 定制选项,你不得不在 Vue Loader 自己的 loaders 选项中将它重复一遍。在 v15 中你再也没有必要这么做了。 拿官方脚手架来说, 可以看到两个函数,用来生成 vue-loader 的 options 还有 module.rule, 我把他们摘出来,就可以看出来了。

// util.jsexports.cssLoaders = function (options) {   // ...}// Generate loaders for standalone style files (outside of .vue)exports.styleLoaders = function (options) {  // ...}复制代码
// vue-loader-conf.jsmodule.exports = {  loaders: utils.cssLoaders({    sourceMap: sourceMapEnabled,    extract: isProduction  }),  ...}复制代码
// webpack.dev.configconst devWebpackConfig = merge(baseWebpackConfig, {  module: {    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })  },  ...}复制代码

我刚入脚手架的坑的时候都蒙了,为什么要这样写,为了德玛西亚么?当然不是,是因为填 vue-loader v14 的坑 vue-loader v15版本只要写一遍就好了,但是要注意请确保在你的 webpack 配置中添加 Vue Loader 的插件

// webpack.config.jsconst VueLoaderPlugin = require('vue-loader/lib/plugin')module.exports = {  module: {    rules: [      {        test: /\.vue$/,        loader: 'vue-loader'      },      // ...    ]  },  plugins: [    // 请确保引入这个插件!    new VueLoaderPlugin()  ]}复制代码

然后由于生产和测试环境对 css 文件处理不同。在webpack.dev.config.js和webpack.prod.config.js里分别配置 less/scss css 的loader就好了:

{  module: {    rules: [      // ...      {        test: /\.less$/,        use: [          'vue-style-loader',          'css-loader',          'less-loader'        ]      }    ]  }}复制代码

mini-css-extract-plugin css 抽取

webpack v4 官方不在推荐使用 extract-text-webpack-plugin 了,改换 mini-css-extract-plugin

// webpack4npm install -D mini-css-extract-plugin// webpack.config.jsvar MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = {  // 其它选项...  module: {    rules: [      // ... 忽略其它规则      {        test: /\.css$/,        use: [          process.env.NODE_ENV !== 'production'            ? 'vue-style-loader'            : MiniCssExtractPlugin.loader,          'css-loader'        ]      }    ]  },  plugins: [    // ... 忽略 vue-loader 插件    new MiniCssExtractPlugin({      filename: style.css    })  ]}复制代码
// webpack3npm install -D extract-text-webpack-plugin// webpack.config.jsvar ExtractTextPlugin = require("extract-text-webpack-plugin")module.exports = {  // 其它选项...  module: {    rules: [      // ...其它规则忽略      {        test: /\.css$/,        loader: ExtractTextPlugin.extract({          use: 'css-loader',          fallback: 'vue-style-loader'        })      }    ]  },  plugins: [    // ...vue-loader 插件忽略    new ExtractTextPlugin("style.css")  ]}复制代码

福利

对webpack3官方脚手架还不是很了解的同学可以看我根据自己理解写的注释,详情点 觉得麻烦,不想自己搞?那也没关系,我自己按照脚手架改了一套,感兴趣的可以试试点 觉得不错请star哦,另外,我准备在下一篇文章中将如何如优化webpack,喜欢的话可关注

参考

转载地址:http://nmvoo.baihongyu.com/

你可能感兴趣的文章
[03] react 测试
查看>>
Python文件指针与Python函数
查看>>
ORM系列之Entity FrameWork详解
查看>>
[转] java Class类
查看>>
编码转换
查看>>
MVC报错的坑
查看>>
那些争议最大的编程观点
查看>>
极简科普 1:什么是 VOIP
查看>>
11.10 (下午)开课二个月零六天(ajax验证用户名,ajax调数据库)
查看>>
PXC 避免加入集群时发生SST
查看>>
JS基础语法
查看>>
python 的一些tip 02
查看>>
int转字符串 stringstream
查看>>
pip升级时报错--- No module named 'pip._internal'
查看>>
大白话搞懂什么是同步/异步/阻塞/非阻塞
查看>>
Fiddler抓包工具总结二(转自小坦克)
查看>>
JSP----动态网页开发的基础
查看>>
CentOS 6.5下部署日志服务器 Rsyslog+LogAnalyzer+MySQL
查看>>
[TFS]安装/升级TFS2012
查看>>
HLG 1408 漩涡
查看>>