wuqiong7 / Note

杂记
3 stars 0 forks source link

关于webpack4 #16

Open wuqiong7 opened 5 years ago

wuqiong7 commented 5 years ago

最大的两个亮点

若只是跑个Hello world的App,那确实webpack.config.js会简但很多。

entry和output都有默认值,
配置mode(webpack4新增,可选值:production / development / none),
加个js loader,配置下devServer就可以跑起来了

entry 的默认值是 ./src,output.path 的默认值是 ./dist

各mode配置下的defalut

有一个隐藏的none模式,用于关闭所有优化。

production模式defalut配置/插件

optimization: {
  noEmitOnErrors: true,
  minimizer: true,
  concatenateModules: true,
}
plugins: [
  new webpack.DefinePlugin({
    "process.env.NODE_ENV": JSON.stringify("production")
  }),
]

development模式defalut配置配置/插件

output: {
  pathinfo: true,
}
optimization: {
  namedModules: true,
}
plugins: [
  new webpack.DefinePlugin({
    "process.env.NODE_ENV": JSON.stringify("development")
  }),
]

Plugins

noEmitOnErrors

告诉reloader在出现错误时不要重载,适合在生产环境

// webpack3
new webpack.NoEmitOnErrorsPlugin()

// webpack4
optimization: {
  noEmitOnErrors: true,
}

concatenateModules

作用域提升 webpack3的scope hosting

// webpack3需手动开启:
new webpack.optimize.ModuleConcatenationPlugin()

??? 这里有个相关mainFields配置阅读,反正我是没理解

同时,考虑到 Scope Hoisting 依赖源码需采用 ES6 模块化语法,还需要配置 mainFields。因为大部分 Npm 中的第三方库采用了 CommonJS 语法,但部分库会同时提供 ES6 模块化的代码,为了充分发挥 Scope Hoisting 的作用,需要增加以下配置 mainFields用于配置第三方模块使用那个入口文件

namedModules

在热加载时直接返回更新文件名,而不是文件的id。 log日志对比:

前:
[HMR] Updated modules:
[HMR] - 324
[HMR] App is up to date.

后:
[HMR] Updated modules:
[HMR] - ./src/frame/frame.js
[HMR] App is up to date.

// webpack3
new webpack.NamedModulesPlugin()

// webpack4
optimization: {
  namedModules: true,
}

webpack.DefinePlugin

定义全局变量,最常用是用来处理我们开发环境和生产环境的不同

new webpack.DefinePlugin({
  __DEV__: clientIsDev,
  __PRO__: !clientIsDev,
}),

mini-css-extract-plugin

原来用于js css分离的extract-text-webpack-plugin 不支持webpack4, 所以改用mini-css-extract-plugin

目前不支持HMR

需要注意的是 MiniCssExtractPlugin.loader 和 style-loader 由于某种原因不能共存。
且mini-css-extract-plugin目前不支持HMR

{
  test: /\.styl$/,
  use: [
    clientIsDev ? 'style-loader' : MiniCssExtractPlugin.loader,
    'css-loader',
    'postcss-loader',
    'stylus-loader',
  ],
  include: [path.resolve(__dirname, 'src')],
  exclude: /node_modules/,
},

new MiniCssExtractPlugin({
  filename: '[name].css',
  chunkFilename: '[name].css',
}),

公用代码抽取

具体可参阅提取公共代码与第三方代码

OptimizeCssAssetsPlugin

用于优化css文件

new OptimizeCSSAssetsPlugin({
  cssProcessorOptions: {
    parser: safeParser,
    discardComments: {
      removeAll: true,
    },
  },
}),

暴露全局变量

new Webpack.ProvidePlugin({
  '$': 'jquery'
})

resolve解析

extensions: 指定extension之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配

resolve: {
 extensions: ['.js', '.json', '.css']
}

清空dist

new CleanWebpackPlugin([path.join(__dirname, 'dist')]),

一些CHANGELOG

extensions

第一个字符是''会包错

// webpack3
extensions: [‘’, ‘.js’, ‘.jsx’]

// webpack4
extensions: ['.js', '.jsx', '.json'],

LOG

参阅文档

wuqiong7 commented 4 years ago

注意:前边是可用的全局变量的名称,后边是NPM包名称

new Webpack.ProvidePlugin({
  '_': 'lodash',
  'lodash': 'lodash',
  '$': 'jquery',
  'jQuery': 'jquery',
})

经测下边这样的写法也好使,但还是推荐规范写法。

new Webpack.ProvidePlugin({
  '_': 'lodash',
  'lodash': '_',
})