webpack文档 阅读笔记
参考
https://webpack.js.org/concepts/
警告!虽然有.com
的中文文档,但是存在没有更新文档的问题,不是webpack4版本的文档!!例如CommonsChunkPlugin已经被弃用,CleanWebpackPlugin的引入和使用方法不同版本不同
核心概念
入口entry
对应配置中的entry
属性
如webpack.config.js
1 | module.exports = { |
常见 分离应用程序和三方库入口
1 | const config = { |
根据经验:每个 HTML 文档只使用一个入口起点。多页面应用
1 | const config = { |
注意 以上都可以用CommonsChunkPlugin
来优化公用代码
输出output
在哪里输出所建立的bundles以及命名
1 | const path = require('path'); |
多个入口起点
1 | { |
高级
用hash或者 运行时path
loader
webpack 本身只理解js,
loader 可以 把所有类型 转换为 webpack可以处理 引用的模块
test
: 哪些文件应该被转换处理
use
: 转换应该使用哪个loader
1 | const path = require('path'); |
例如ts
和css
的loader
1 | npm install --save-dev css-loader |
1 | module.exports = { |
在上面use中也可以1个test,数组的use,
除了配置还有import Styles from 'style-loader!css-loader?modules!./styles.css';
内联写法
和CLI写法webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
这样.jade
和.css
用不同的loader
插件plugins
和loader相比,loader 主要用于转换某些类型的模块
而 plugins一般功能范围更广,从打包优化,压缩,一直到重新定义环境中的变量
例如
1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 |
定位 完成loader 无法实现的其它事
一个插件 是 具有apply方法的class,它的apply会被webpack compiler调用
配置使用:需要new
样例:
1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装 |
通过node主动 调用 webpack示例
1 | const webpack = require('webpack'); //访问 webpack 运行时(runtime) |
模式mode
通过选择development
或production
之中的一个,来设置mode
参数,你可以启用相应模式下的webpack
内置的优化
1 | module.exports = { |
或者从cli传递webpack --mode=production
差异
建立不同的配置文件webpack.development.config.js
和webpack.production.config.js
development
会将 process.env.NODE_ENV
的值设为 development
。启用 NamedChunksPlugin
和 NamedModulesPlugin
。
production
会将 process.env.NODE_ENV
的值设为 production
。启用 FlagDependencyUsagePlugin
, FlagIncludedChunksPlugin
, ModuleConcatenationPlugin
, NoEmitOnErrorsPlugin
, OccurrenceOrderPlugin
, SideEffectsFlagPlugin
和 UglifyJsPlugin
.
模块
关于模块引入 分为3种
- 绝对路径
- 相对路径
- 模块路径,将在
resolve.modules
中指定的所有目录内搜索,
一旦根据上述规则解析路径后,解析器(resolver)将检查路径是否指向文件或目录。如果路径指向一个文件:
- 如果路径具有文件扩展名,则被直接将文件打包。
- 否则,将使用 [resolve.extensions] 选项作为文件扩展名来解析,此选项告诉解析器在解析中能够接受哪些扩展名(例如 .js, .jsx)。
如果路径指向一个文件夹,则采取以下步骤找到具有正确扩展名的正确文件:
- 如果文件夹中包含 package.json 文件,则按照顺序查找 resolve.mainFields 配置选项中指定的字段。并且 package.json 中的第一个这样的字段确定文件路径。
- 如果 package.json 文件不存在或者 package.json 文件中的 main 字段没有返回一个有效路径,则按照顺序查找 resolve.mainFiles 配置选项中指定的文件名,看是否能在 import/require 目录下匹配到一个存在的文件名。
- 文件扩展名通过 resolve.extensions 选项采用类似的方法进行解析。
manifest
在使用 webpack 构建的典型应用程序或站点中,有三种主要的代码类型:
- 你或你的团队编写的源码。
- 你的源码会依赖的任何第三方的 library 或 “vendor” 代码。
- webpack 的 runtime 和 manifest,管理所有模块的交互。
__webpack_require__
+manifest
来做运行时模块检索
target
1 | var path = require('path'); |
打分别服务端js和 网页端js
模块热替换(hot module replacement)
webpack watch mode
webpack-dev-server
webpack-dev-middleware
…
使用webpack
编写代码
配置webpack.config.json
webpack-cli
1 | npm i webpack-cli @webpack-cli/init |
例如ts支持
npm install --save-dev typescript ts-loader
增加tsconfig.json
文件
1 | { |
编辑webpack.config.js
把index.js
换为index.ts
1 | module.exports = { |
在module.exports.module.rules
增加
1 | module: { |
然后新建文件index.ts
plugins
用已有的就见文档了
说说自定义plugins:
https://webpack.js.org/contribute/writing-a-plugin/#creating-a-plugin
你需要实现
1 | class MyExampleWebpackPlugin { |
关于所有hook可以看https://webpack.js.org/api/compiler-hooks/
也可以输出 compiler.hooks
的key
Compiler 和 Compilation 源码
https://github.com/webpack/webpack/blob/master/lib/Compiler.js
https://github.com/webpack/webpack/blob/master/lib/Compilation.js
一个既有compiler
也有compilation
的
1 | function HelloCompilationPlugin(options) {} |
坑
如果使用 init 生成,在填写entry point的时候不是文件夹,则在你生成的webpack.config.js
的 loader的include有问题可能为[]
例如实现代码见~/.npm_global/lib/node_modules/@webpack-cli/init/node_modules/@webpack-cli/generators/utils/languageSupport.js
的 getTypescriptLoader
等的include实现,也就是getEntryFolders
返回为空
https://github.com/webpack/webpack-cli/pull/817/files