昨天有关 Webpack 笔记也是有许多人喜好的,因此今天再接再砺汇总了第二篇笔记,欢迎各位指点不足之处。
以后的笔记应该会记录一些实际开发了,但愿在这个周末内完全入门 Webapck。css
mode 配置项是 webpack4 新增的配置项,这个配置项是必须的。html
若是使用的不是 webpack4 ,该配置项了解一下便可,使用了 webpack4 以上版本,也能够了解一下便可。
事实上它并不是必须的,可是若是忽略它, webpack 会有个警告。vue
该配置项的属性值类型是 String,并有三个可选项:node
production 默认值会给你提供一系列有效的默认值以便部署你的应用,它注重:react
该默认顾名思义是注重最好的开发体验,它注重:jquery
当人对于初学者来讲,对于 webpack 的优化还有一段距离,首先咱们大致了解一下便可。webpack
它还有不少其余的优化默认值,可是效果可能并不美好,由于它针对的某些特定的大型项目,而咱们只是入门,因此了解便可。web
module 中配置处理模块的规则。正则表达式
rules 配置模块的读取和解析规则,一般用来配置 Loader。其类型是一个数组,数组里每一项都描述了如何去处理部分文件。配置一项 rules 时大体可经过如下方式来实现:npm
module: {
rules: [
{
// 命中 JavaScript 文件
test: /\.js$/,
// 用 babel-loader 转换 JavaScript 文件
// ?cacheDirectory 表示传给 babel-loader 的参数,用于缓存 babel 编译结果加快从新编译速度
use: ['babel-loader?cacheDirectory'],
// 只命中src目录里的js文件,加快 Webpack 搜索速度
include: path.resolve(__dirname, 'src')
},
{
// 命中 SCSS 文件
test: /\.scss$/,
// 使用一组 Loader 去处理 SCSS 文件。
// 处理顺序为从后到前,即先交给 sass-loader 处理,再把结果交给 css-loader 最后再给 style-loader。
use: ['style-loader', 'css-loader', 'sass-loader'],
// 排除 node_modules 目录下的文件
exclude: path.resolve(__dirname, 'node_modules'),
},
{
// 对非文本文件采用 file-loader 加载
test: /\.(gif|png|jpe?g|eot|woff|ttf|svg|pdf)$/,
use: ['file-loader'],
},
]
}
复制代码
上面的例子基本将配置 loader 的大部分配置项都涵盖了,很是清晰简洁。
// 使用一组 Loader 去处理 SCSS 文件。
// 处理顺序为从后到前,即先交给 sass-loader 处理,再把结果交给 css-loader 最后再给 style-loader。
use: ['style-loader', 'css-loader', 'sass-loader']
复制代码
在上面的例子中,对于多 Loader 处理方式中,采用的是数组,执行数序为从左到右
除此以外,咱们还能够经过一个 Object 方式来写这一块的代码
use: [
{
loader:'babel-loader',
options:{
cacheDirectory:true,
},
// enforce:'post' 的含义是把该 Loader 的执行顺序放到最后
// enforce 的值还能够是 pre,表明把 Loader 的执行顺序放到最前面
enforce:'post'
},
// 省略其它 Loader
]
复制代码
对于 Loader 的最后一点补充就是关于命中文件的三个配置项:text、 include、 exclude。
在上述例子中,这三兄弟的配置只传入了一个字符串或者是正则,其实他们还均可以支持数组,数组之间的关系为 “或”的关系,即文件知足数组中的任何一个条件,都会被命中。
noParse 配置项可让 Webpack 忽略对部分没采用模块化的文件的递归解析和处理,这样作的好处是能提升构建性能。 缘由是一些库例如 jQuery 、ChartJS 它们庞大又没有采用模块化标准,让 Webpack 去解析这些文件耗时又没有意义。
noParse 是可选配置项,类型须要是 RegExp、[RegExp]、function 其中一个。
// 使用正则表达式
noParse: /jquery|chartjs/
// 使用函数,从 Webpack 3.0.0 开始支持
noParse: (content)=> {
// content 表明一个模块的文件路径
// 返回 true or false
return /jquery|chartjs/.test(content);
}
复制代码
注意被忽略掉的文件里不该该包含 import 、 require 、 define 等模块化语句,否则会致使构建出的代码中包含没法在浏览器环境下执行的模块化语句。
由于 Webpack 是以模块化的 JavaScript 文件为入口,因此内置了对模块化 JavaScript 的解析功能,支持 AMD、CommonJS、SystemJS、ES6。 parser 属性能够更细粒度的配置哪些模块语法要解析哪些不解析,和 noParse 配置项的区别在于 parser 能够精确到语法层面, 而 noParse 只能控制哪些文件不被解析。 parser 使用以下:
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
parser: {
amd: false, // 禁用 AMD
commonjs: false, // 禁用 CommonJS
system: false, // 禁用 SystemJS
harmony: false, // 禁用 ES6 import/export
requireInclude: false, // 禁用 require.include
requireEnsure: false, // 禁用 require.ensure
requireContext: false, // 禁用 require.context
browserify: false, // 禁用 browserify
requireJs: false, // 禁用 requirejs
}
},
]
}
复制代码
该配置项主要是配置 Webapck 如何寻找模块所对应的文件。
Webpack 内置 JavaScript 模块化语法解析功能,默认会采用模块化标准里约定好的规则去寻找,但你也能够根据本身的须要修改默认的规则。
该配置项的属性蛮多的,可是我以为我能用获得的也就几个=。=
resolve.alias 配置项经过别名来把原导入路径映射成一个新的导入路径。例如使用如下配置:
// Webpack alias 配置
resolve:{
alias:{
components: './src/components/'
}
}
复制代码
当你经过 import Button from 'components/button' 导入时,实际上被 alias 等价替换成了 import Button from './src/components/button'。
以上 alias 配置的含义是把导入语句里的 components 关键字替换成 ./src/components/。
这样作可能会命中太多的导入语句,alias 还支持 $ 符号来缩小范围到只命中以关键字结尾的导入语句:
resolve:{
alias:{
'react$': '/path/to/react.min.js'
}
}
复制代码
react$ 只会命中以 react 结尾的导入语句,即只会把 import 'react' 关键字替换成 import '/path/to/react.min.js'。
该方法的应用场景有待我去探索,真不太清楚这样替换的缘由。
可是我以为是蛮有用的。
在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试访问文件是否存在。 resolve.extensions 用于配置在尝试过程当中用到的后缀列表,默认是:
extensions: ['.js', '.json']
这个配置项应该有用,在处理 TypeScript、vue 这些文件的时候,能够设置一下
resolve.enforceExtension 若是配置为 true 全部导入语句都必需要带文件后缀, 例如开启前 import './foo' 能正常工做,开启后就必须写成* import './foo.js'。*
对于 Resolve 的其余配置项,大致了解一下便可,我以为可能用的不是特别多。
对于 Plugins 的使用,上一节也写到过,仍是那句话吧:
使用 Plugin 的难点在于掌握 Plugin 自己提供的配置项,而不是如何在 Webpack 中接入 Plugin。
使用 DevServer 能干啥?
DevServer 会启动一个 HTTP 服务器 用于服务网页请求,同时会帮助启动 Webpack,并接收 Webpack 发出的文件更新信号,经过 webSocket 协议自动刷新网页作到实时预览。
集成 DevServer ,首先须要安装一下:
npm i -D webpack-dev-server
复制代码
若是不是经过 npm run 启动,直接将 webpack-dev-server 安装到全局,直接使用,会报: webpack-dev-server: command not found
安装成功后,执行 webpack-dev-server 命令,接着一连串日志输出:
i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /
i 「wdm」: Hash: 5cece8a0d7243a4cf1ba
Version: webpack 4.8.3
Time: 1627ms
Built at: 2018-05-18 14:18:57
......
复制代码
用浏览器直接打开这个地址你会发现页面空白,错误缘由是 ./dist/bundle.js 加载404了。 同时你会发现并无文件输出到 dist 目录,缘由是 DevServer 会把 Webpack 构建出的文件保存在内存中,在要访问输出的文件时,必须经过 HTTP 服务访问。 因为 DevServer 不会理会 webpack.config.js 里配置的 output.path 属性,因此要获取 bundle.js 的正确 URL 是 http://localhost:8080/bundle.js
webpack --watch 会开启监听模式,而 webpack 启动默认是关闭的,开启 DevServer 默认开启监听模式,因此修改须要被打包的文件浏览器会被自动刷新,这里主要应用到了 Websocket ,有须要的童鞋能够去了解一下。
若是尝试修改 index.html 文件并保存,你会发现这并不会触发以上机制,致使这个问题的缘由是 Webpack 在启动时会以配置里的 entry 为入口去递归解析出 entry 所依赖的文件,只有 entry 自己和依赖的文件才会被 Webpack 添加到监听列表里。 而 index.html 文件是脱离了 JavaScript 模块化系统的,因此 Webpack 不知道它的存在。
能够尝试用 raw-loader 来处理一下 html
固然上述实现页面更改都是基于页面刷新实现的,DevServer 还有一种被称做模块热替换的刷新技术——热更新。
DevServer 默认是关闭热更新的,能够经过
webpack-dev-server --hot
复制代码
来开启
webpack-dev-server --devtool source-map
复制代码
这个功能就很少说了。
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
hot: true,
open: 'http://127.0.0.1:9000',
// inline: true,
// contentBase: path.join(__dirname, "dist"),
compress: true,
port: 9000
}
复制代码
devServer 的配置项也是蛮多的,看了很久,发现有用的也就是这几个吧:
该配置项还有不少其余的属性,我以为目前我是用不上,但不妨碍咱们了解一下,在此我就不一一记录了。
webpack 的基本操做到目前为止基本结束,他能完成的功能仍是有不少的,从它的 N 多配置项就能看出来,但咱们不须要所有记住,记住以前的核心概念和它的基本原理就能够,以后再根据本身的经验去判断它属于哪一块再去查文档就没问题。
webpack4:模式与优化
深刻浅出 Webpack
webpack 配置项
[HMR] Hot Module Replacement is disabled
Gzip