基础知识不介绍,只记录之前自己的坑点
Webpack 是一个打包模块化 JavaScript 的工具,它会从 main.js 出发,识别出源码中的模块化导入语句, 递归的寻找出入口文件的所有依赖,把入口和其所有依赖打包到一个单独的文件中。 从 Webpack2 开始,已经内置了对 ES6、CommonJS、AMD 模块化语句的支持。
一
Webpack 把一切文件看作模块,CSS 文件也不例外,要引入 main.css 需要像引入 JavaScript 文件那样,修改入口文件 main.js 如下:
二
// 通过 CommonJS 规范导入 CSS 模块
require('./main.css');
// 通过 CommonJS 规范导入 show 函数
const show = require('./show.js');
// 执行 show 函数
show('Webpack');
三 在webpack.config.js配置文件中配置css的loader
module: {
rules: [
{
// 用正则去匹配要用该 loader 转换的 CSS 文件
test: /.css$/,
use: ['style-loader', 'css-loader?minimize'],
}
]
}
注意: use 属性的值需要是一个由 Loader 名称组成的数组,Loader 的执行顺序是由后到前的;
每一个 Loader 都可以通过 URL querystring 的方式传入参数,例如 css-loader?minimize 中的 minimize 告诉 css-loader 要开启 CSS 压缩。
加入css后重新构建发现bundle.js
文件被更新了,里面注入了在 main.css
中写的 CSS,而不是会额外生成一个 CSS 文件。 但是重新刷新 index.html
网页时将会发现 Hello,Webpack
居中了,样式生效了! 也许你会对此感到奇怪,第一次看到 CSS 被写在了 JavaScript 里!这其实都是 style-loader
的功劳,它的工作原理大概是把 CSS 内容用 JavaScript 里的字符串存储起来, 在网页执行 JavaScript 时通过 DOM 操作动态地往 HTML head
标签里插入 HTML style
标签。 也许你认为这样做会导致 JavaScript 文件变大并导致加载网页时间变长,想让 Webpack 单独输出 CSS 文件可以通过 Webpack Plugin 机制来实现。
给 Loader 传入属性的方式除了有 querystring 外,还可以通过 Object 传入,以上的 Loader 配置可以修改为如下:
use: [
'style-loader',
{
loader:'css-loader',
options:{
minimize:true,
}
}
]
除了在 webpack.config.js 配置文件中配置 Loader 外,还可以在源码中指定用什么 Loader 去处理文件。 以加载 CSS 文件为例,修改上面例子中的 main.js 如下:
require('style-loader!css-loader?minimize!./main.css'); // 这方方式超级帅的有没有!!!
四 DevServer
需求来源:
提供 HTTP 服务而不是使用本地文件预览;
监听文件的变化并自动刷新网页,做到实时预览;
支持 Source Map,以方便调试。
对于这些, Webpack 都为你考虑好了。Webpack 原生支持上述第2、3点内容,再结合官方提供的开发工具 也可以很方便地做到第1点。 DevServer 会启动一个 HTTP 服务器用于服务网页请求,同时会帮助启动 Webpack ,并接收 Webpack 发出的文件更变信号,通过 WebSocket 协议自动刷新网页做到实时预览。
安装webpack-dev-server;
npm i webpack-dev-server --save-dev
注意: 安装成功后我们就可以以dev的模式来启动webpack了,但是此时如果你直接在控制台运行 webpack-dev-server 这条命令,会得到一个没有此命令的错误,必须要在package.json的script字段中配置启动命令 ’server': 'webpack-dev-server --inline --hot --devtool source-map'
然后运行 npm run server 就可以正常的启动了。至于为甚么非要配置脚本命令,我还没想明白,应该是shell上 的问题,也许等我学完Linux之后这个问题能明白。
启动之后DevServer 启动的 HTTP 服务器监听在 http://localhost:8080/ ,DevServer 启动后会一直驻留在后台保持运行,访问这个网址你就能获取项目根目录下的 index.html。 用浏览器打开这个地址你会发现页面空白错误原因是 ./dist/bundle.js 加载404了。(这个错误在初次启动后访问的时候也许并不会出现) 同时你会发现并没有文件输出到 dist 目录,原因是 DevServer 会把 Webpack 构建出的文件保存在内存中,(这点是对的)在要访问输出的文件时,必须通过 HTTP 服务访问。 由于 DevServer 不会理会 webpack.config.js 里配置的 output.path 属性,所以要获取 bundle.js 的正确 URL 是 http://localhost:8080/bundle.js,对应的 index.html 对bundle.js文件的引用要改成<script src="bundle.js"></script> (之前是<script src="./dist/bundle.js"></script>)改成这样之后,你再修改js文件,webpack就能自动重新构建然后刷新浏览器了。
(这里补充一个细节:
Webpack 在启动时可以开启监听模式,开启监听模式后 Webpack 会监听本地文件系统的变化,发生变化时重新构建出新的结果。Webpack 默认是关闭监听模式的,你可以在启动 Webpack 时通过 webpack --watch 来开启监听模式。
通过 DevServer 启动的 Webpack 会开启监听模式,当发生变化时重新执行完构建后通知 DevServer。 DevServer 会让 Webpack 在构建出的 JavaScript 代码里注入一个代理客户端用于控制网页,网页和 DevServer 之间通过 WebSocket 协议通信, 以方便 DevServer 主动向客户端发送命令。 DevServer 在收到来自 Webpack 的文件变化通知时通过注入的客户端控制网页刷新。
如果尝试修改 index.html 文件并保存,你会发现这并不会触发以上机制,导致这个问题的原因是 Webpack 在启动时会以配置里的 entry 为入口去递归解析出 entry 所依赖的文件,只有 entry 本身和依赖的文件才会被 Webpack 添加到监听列表里。 而 index.html 文件是脱离了 JavaScript 模块化系统的,所以 Webpack 不知道它的存在。
) 书讲的多好啊
五 模块热更新
除了通过重新刷新整个网页来实现实时预览,DevServer 还有一种被称作模块热替换的刷新技术。 模块热替换能做到在不重新加载整个网页的情况下,通过将被更新过的模块替换老的模块,再重新执行一次来实现实时预览。 模块热替换相对于默认的刷新机制能提供更快的响应和更好的开发体验。 模块热替换默认是关闭的,要开启模块热替换,你只需在启动 DevServer 时带上 --hot 参数,重启 DevServer 后再去更新文件就能体验到模块热替换的神奇了
(我上面的脚步命令已经配置了--hot)
六 source map
在浏览器中运行的 JavaScript 代码都是编译器输出的代码,这些代码的可读性很差。如果在开发过程中遇到一个不知道原因的 Bug,则你可能需要通过断点调试去找出问题。 在编译器输出的代码上进行断点调试是一件辛苦和不优雅的事情, 调试工具可以通过 Source Map 映射代码,让你在源代码上断点调试。 Webpack 支持生成 Source Map,只需在启动时带上 --devtool source-map
参数。 加上参数重启 DevServer 后刷新页面,再打开 Chrome 浏览器的开发者工具,就可在 Sources 栏中看到可调试的源代码了。
ok 最后《深入浅出webpack》 这本书真不错,推荐。