file-loader: 处理 html 文件,当前 atool-build 内置的方式,在实际业务中,很多并不希望 html 是拍平的结构,所以他们会自定义 fileloader 的参数,比如 file?name=[path][name].[ext]&context=./src/pages,但是也有不少业务中对 html 处理引入了新的 loader, 有 ejs-html-loader,html-minify-loader,还有直接使用插件 HtmlWebpackPlugin 来处理的情况,经过研究,根本上其实是想要解决 html 的自动化生成,以及内部资源文件的引用可以自动化生成。
webpack.optimize.CommonsChunkPlugin,在业务中通常有两种使用方式,一种是直接从所有的代码中抽取 common 的逻辑,此处可以配置 common 抽取最小单元,还有一种 common 的使用方式是 vendor 即用户配置具体的 entry 条目,并把该条目抽取为 vendor。
webpack.optimize.OccurenceOrderPlugin:优化插件,优化 module id
最近调研了所有 atool-build 使用方的代码,大概近千个项目,总结了一些常用的 webpack 方式,记录如下:
entry
entry 是描述一个 bundle 的入口文件是什么。在具体在业务中使用的方式有如下三种:
output
output 的作用在于告知 webpack 该如何把构建编译后的文件放入到磁盘。
在具体业务中使用的方式有如下种:
output.filename
: 修改构建后文件的命名,业务中会存在 4 种情况。output.path
: 修建构建后文件输出到磁盘的目录,业务中会存在 1 种情况。output.publicPath
: 申明构建后的资源文件的引入地址,业务中会存在 1 种情况https://xxxx.xx.com/assets/
这种方式,这种方式的出现在于 webpack 默认在引用资源时都是从根目录开始,然后现实中 assets 资源 和 html 会随不同的发布平台发布。output.chunkFilename
:声明非 entry chunks 的资源文件的命名,一般它发生的场景在 code split 即按需加载的业务场景,例如require.ensure
,在这种场景下,会对require.ensure
的模块进行独立的打包,文件命名也会有四种情况。require.ensure(dependencies: String[], callback: function(require), errorCallback: function(error), chunkName: String)
output.library
:一旦设置后该 bundle 将被处理为 library。output.libraryTarget
:export 的 library 的规范,有支持var
,this
,commonjs
,commonjs2
,amd
,umd
。resolve
resolve.alias
:为模块设置别名。这种方案通常使用在两种情况下:../
等这种路径操作,另外也可以提升 webpack 在 resolve 模块时的速度;resolve.alias.a = isTest ? 'moduleTestA' : 'moduleA'
,如上这种方式使用最大的好处在于能根据当前所属代码所需情况构建产物中只会有moduleTestA
或者moduleA
。以上这种方式可以在所有资源文件应用。当然也可以使用babel-plugin-module-resolver
和less-plugin-rewrite-import
予以解决。resolve.root
:添加个人目录到 webpack 查找模块的路径里,这种需求比如发生在当前某个项目所依赖某个文件并不在该项目中。resolve.modulesDirectories
:模块解析方式,在项目中我看到一般会有两种使用的场景,["node_modules", "bower_components"]
那么在项目中 foo/bar 的文件下依赖一个模块 a, 那么 webpack 会通过如下的顺序去寻找依赖resolve.extensions
:设置解析模块的拓展名。默认为["", ".webpack.js", ".web.js", ".js"]
。比如新增一种文件扩展名,["", ".webpack.js", ".web.js", ".web.ts", ".web.tsx", ".js"]
resolve.packageMains
:设置main
的入口文件。这种方式目前会在 webpack@2 中使用resolve.mainFields
来解决 tree-shaking,目前支持的有 redux 等。resolveLoader
resolveLoader.modulesDirectories
:同 resolve.modulesDirectories 只不过针对 loader,这边需要注意的是在 resolve.modulesDirectories 中关于优先级的,在工具被二次封装时会用到比较多。resolveLoader.moduleTemplates
:["*-webpack-loader", "*-web-loader", "*-loader", "*"]
webpack@1 中内置的模板,但是在 webpack@2 是并不会补齐。resolve.root, resolve.fallback, resolve.modulesDirectories 这三个属性在 webpack@2 中被合并到了 resolve.modules
module
module.loaders
:对应模块的加载器。在 webpack@2 中使用 module.rules 予以取代。以下会罗列目前常用文件类型的模块加载处理方式。babel-loader
处理.js
和.jsx
文件,由于历史原因 atool-build 在处理.jsx
文件时会处理node_modules
下内容。babel-preset-es2015-ie
,babel-preset-react
,babel-preset-stage-0
,plugins 有babel-plugin-add-module-exports
和babel-plugin-transform-decorators-legacy
。babel-plugin-import
构建资源大小提供优化,babel-plugin-transform-runtime
实现按需加载 pollyfill 需要与 babel-runtime 结合使用,babel-plugin-module-resolver
实现诸如 webpack 中 resolve.alias 功能,babel-plugin-dva-hmr
和babel-plugin-dev-expression
实现 dva hot module replacement 功能,babel-plugin-react-intl
实现 react 多语言方案,babel-plugin-es6-promise
覆盖原有 promise; preset:babel-preset-env
实现根据浏览器支持情况自动打包 pollyfill 等功能,babel-preset-es2016
等。在实际过程中,都可能需要对 preset 传入参数的需求。一般设置如下presets: [[require.resolve('xxx-preset'), { options: hi }]]
cacheDirectory
:缓存支持,一般默认就开启babelrc
:一般需要禁用掉,防止用户端的 babel 配置影响内置配置tsx-loader
: 处理 ts 文件,内置参数target: 'es6', jsx: 'preserve',moduleResolution: 'node', declaration: false, sourceMap: true
,需要注意的是在使用 ts 项目时必须要人为引入一个 ts config.json 的文件,如果没有内容,内部设置为一个空对象即可。style-loader
: 通过 js 方式 inject style 节点来注入样式,一般用于开发环境css-loader
: 处理 css 文件,一般现有项目中都会使用 ExtractTextPlugin 把样式文件抽取出来,但是在本地开发环境下一般不会 extract 出来,因为一旦 extract 出来会导致 hmr 对样式失效。所以一般在开环环境下会style-loader!css-loader!postcss-loader
而在 production 下采用ExtractTextPlugin
,另外在每个 loader 都有对应的参数,postcss 还有专门的插件集。除此之外,常用的 css-loader 参数有 modules autoprefix indentName 等postcss-loader
: 目前在 postcss 中内置的 plugin 有rucksack-css
- 可废弃 和autoprefixer
用以实现 autoprefix。一般针对适配的不同的浏览器,需要对 autoprefixer 配置browsers
参数。一般在无线业务中为了适配高清方案也会引入postcss-plugin-pxtorem
, 同时也需要设置一些参数。less-loader
: 处理 less 文件,一般情况下需要配置 modifyVars 参数,用以覆盖 less 变量值sass-loader
: 处理 sass 文件,也有使用fast-sass-loader
和@ali/sass-loader
file-loader
: 处理 html 文件,当前 atool-build 内置的方式,在实际业务中,很多并不希望 html 是拍平的结构,所以他们会自定义 fileloader 的参数,比如file?name=[path][name].[ext]&context=./src/pages
,但是也有不少业务中对 html 处理引入了新的 loader, 有ejs-html-loader
,html-minify-loader
,还有直接使用插件HtmlWebpackPlugin
来处理的情况,经过研究,根本上其实是想要解决 html 的自动化生成,以及内部资源文件的引用可以自动化生成。url-loader
: 处理 woff woff2 ttf eot svg png jpg jpeg gif 文件,目前业务中会有变更的点有,需要设置limit
的大小,以及 svg 的处理可能需要存在多个 loader 处理,因为在使用 antd-mobile 业务中需要新增一个svg-sprite-loader
来把 svg 文件当成一个 componentsvg-sprite-loader
, 已在 url-loader 中予以说明HtmlWebpackPlugin
, 已在 file-loader 中予以说明ejs-html-loader
, 已在 file-loader 中予以说明html-minify-loader
, 已在 file-loader 中予以说明handlebars-loader
, 处理 .handlebars 文件,并未内置,业务中自行引入aptl-loader
, 处理.atpl
文件raw-loader
, 处理 tpl 文件,也有使用html-loader
来处理的scss-loader
, 处理 scss 文件vue-loader
, 处理 vue 文件json-loader
, 处理 json 文件 注:一个正常 loader 的配置可能需要配置test
,exclude
,include
,loader
,loaders
属性module.preLoaders
:istanbul-instrumenter
,此方式在 webpack@2 中被弃用,可以直接在对应的应用规则的文件中启用enforce: 'pre'
module.postLoaders
:es3ify-loader
,提升 ie 兼容性,此方式在 webpack@2 中被弃用,可以直接在对应的应用规则的文件中启用enforce: 'post'
module.noParse
: 指明 webpack 不去解析某些内容,该方式有助于提升 webpack 的构建性能,配置内容可以是externals
目前业务中使用都为声明外部依赖,这种方式有益于加速 webpack 构建,但是需要开发者额外引入被 external 库的 cdn 地址,常见的有 React 和 ReactDom。
devtool
文档
node
目前内置如下内容为 empty
plugin - webpack 内置
大部分插件都有需要参数传入
plugin - webpack 扩展
大部分插件都有需要参数传入
需要沉淀的方案