webpack 开发环境一次搞定
前言
一句话说明本文主要介绍什么
分享webpack 开发环境中都需要配置什么?
使用 html-webpack-plugin 产生 index.html
plugins
是个阵列
,因此我们可以配置多个不同的插件:
npm install html-webpack-plugin -D
// ./demos/auto-create-html/webpack.config.js
...
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
...
plugins: [
new HtmlWebpackPlugin()
]
}
配置改变时自动重新建置
由于 Dev Server 的监听范围仅限专案的内容,并不包括其他的档案,因此在上节加上 html-webpack-plugin 的时候,我们修改了 webpack.config.js ,但是并不会重新建置。
这时就需要 nodemon
的帮助,这是一个可以侦测 node.js 程式并自动重载的工具,首先先安装:
npm install nodemon -D
// ./demos/reload-config/package.json
{
"name": "development-mode",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "nodemon --watch webpack.config.js ./node_modules/.bin/webpack-dev-server"
},
"devDependencies": {
"html-webpack-plugin": "^4.5.0",
"nodemon": "^2.0.4",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
Hot Module Replacement
前面的例子虽然在修改档案后会更新浏览器,但如果只是一小部分的修改,就让整个网页重整,会消耗不必要的资源,因此 Dev Server 提供了模组热替换的功能,它能在不重整整个网页的情况下,更新一小部分的内容。
首先要开启 devServer.hot
:
/ ./demos/hmr/webpack.config.js---------------模组热替换-------------------------------
...
module.exports = {
...
devServer: {
hot: true
},
...
}
使用 webpack 开发 JavaScript
@babel/core
: Babel 的核心库,只负责建置的流程,并不会加上转换的处理,这部分是属于 Plugins 的职责。@babel/cli
: Babel 的 CLI 工具,可以下指令控制 Babel 的执行@babel/preset-env
:每个 Plugins 都针对特定的语法处理,假设使用了其他的语法,就必须要个别加上对应的 Plugins ,设定会变得相当复杂,所幸 Babel 提供了 Presets ,Presets 会将多个 Plugins 包起来,供使用者引入所需的 Plugins 。Polyfill
:Babel 的 Plugins 只负责转换语法,并没有对新的语意做解释,这时就要藉由 Polyfill 的帮助。
npm install @babel/core @babel/cli -D
npm install @babel/preset-env -D
npm install core-js
// ./demos/babel-preset/babel.config.js
module.exports = {
presets: ["@babel/preset-env"],
};
// ./demos/babel-polyfill/babel.config.js
module.exports = {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: 3,
},
],
],
};
-
useBuiltIns
: 决定要如何引入 Polyfillfalse
: 预设值,全部手动引入'entry'
: 在入口.js
档中引入完整的core-js
,Babel 会依照环境配置取出对应的 Polyfill'usage'
: Babel 会侦测代码,以引入对应的 Polyfill
-
corejs
:指定core-js
版本
这里配置使用 usage
的方式自动引入 Polyfill 。
将 Babel 加到 webpack 中
使用 babel-loader
将 babel 引入 webpack 的建置流程中:
// ./demos/babel-webpack/webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
},
},
],
},
};
小结:
-
在真实的环境中,虽然 webpack 可以识别 ES2015 的语法,但是浏览器不一定懂,因此还是需要利用 Babel 做转换。
-
Babel 本身不会做任何的转换,需要加上对应的 Plugins 才会有转换的动作,而 Preset 可以将多个 Plugins 包起来,依照目标环境做对应的转换。
-
Plugins 只会转换语法,对于新的语意并不会转换,这时需要藉由
core-js
的 Polyfill 帮助做转换。 -
使用 babel-loader 引入 Babel 至 webpack 的建置流程中,让我们在建置过程中享有 Babel 的功能。
使用webpack处理Style
使用 CLI 设定Style
postcss
: PostCSS 的核心库,负责建置流程postcss-cli
: PostCSS 的 CLI 工具,供使用者使用 CLI 执行 PostCSS使用 postcss-preset-env 转换代码
:现在我们想要将拥有新语法的.css
内容转为旧版本相容的语法,这时就可以藉由 PostCSS 的postcss-preset-env
Plugin
npm install postcss postcss-cli -D
npm install postcss-preset-env -D
cmd执行postcss src/style.css --dir dist --use postcss-preset-env
使用配置档设定 PostCSS
使用 CLI 设定虽然简单,但只要配置复杂,就会变得难以维护,因此 PostCSS 提供了配置档的方式做设定:
// ./demos/postcss-config/postcss.config.js
module.exports = {
map: true,
plugins: [require("postcss-preset-env")()],
};
使用 .browserslistrc
配置目标环境
预设 postcss-preset-env
会将目标对象视为 browserslist 的 defaults
值。
我们可以自己使用 .browserslistrc
做目标的调整:
// ./demos/postcss-browserslist/.browserslistrc
> 5%
重新建置后会发现,变数没有做转换了,这是因为在范围内的浏览器都已经支援 css 变数的语法。
将 CSS 载入至 Webpack 中
npm install postcss-loader -D
// ./demos/postcss-loader/webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "postcss-loader",
},
],
},
],
},
};
使用 css-loader
载入 Style 至 JavaScript 中
npm install css-loader -D
// ./demos/css-loader/webpack.config.js
module.exports = {
mode: "none",
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "css-loader",
},
{
loader: "postcss-loader",
},
],
},
],
},
};
使用 style-loader
载入 CSS 内容至 Document 中
css-loader
只负责解析并载入 .css
内容,并不负责将其载入至 Document 中。 藉由 style-loader
的帮助,可以帮我们嵌入 .css
内容至 Document 中:
npm install style-loader -D
// ./demos/style-loader/webpack.config.js
module.exports = {
mode: "none",
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "postcss-loader",
},
],
},
],
},
};
### 使用mini-css-extract-plugin
将 CSS 拆分至独立档案
在开发环境时,如果样式有问题时,嵌入的 Style 会难以除错,这时如果可以保持独立的 .css 档的状况下,每个 .js 个别引入了哪些样式也可以识别,对于除错是很好的帮助。这时可以借助 mini-css-extract-plugin 的帮助,让我们可以将 css 独立出来成为单一档案由 HTML 引入。
npm install mini-css-extract-plugin -D
-plugin");
module.exports = {
mode: "none",
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: "css-loader",
},
{
loader: "postcss-loader",
},
],
},
],
},
plugins: [new HtmlWebpackPlugin(), new MiniCssExtractPlugin()],
};
这里有几点要注意:
- 不需要使用
style-loader
,因此从中删去 - 加入
mini-css-extract-plugin
的 loader 以处理 CSS - 加入
mini-css-extract-plugin
产生独立的 style 档案 - 加入
html-webpack-plugin
自动引入.js
与.css
档案
命令行一键下载:
npm install postcss-loader css-loader mini-css-extract-plugin html-webpack-plugin -D
webpack载入图片资源
使用file-loader
路径载入
npm install -D file-loader
// ./demos/load-image-by-path/webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "none",
module: {
rules: [
{
test: /\.png$/,
loader: "file-loader",
},
],
},
plugins: [new HtmlWebpackPlugin()],
};
使用 Data URL 载入图片
图片使用路径载入时会需要多一次的请求以取得资源,这对于大图片来说是可以接受的,但对于 icon 之类的小图示,花费多次请求是浪费资源的,数量一多,会造成效能降低。
为了避免多次请求的问题,我们可以将图片转为 Data URL 直接写在引用的位置中,如此一来就不需要再次请求了,为此我们需要引入url-loader
:
npm install url-loader -D
// ./demos/load-image-by-url/webpack.config.js
module.exports = {
mode: "none",
module: {
rules: [
{
test: /\.png$/,
use: [
{
loader: "url-loader",
},
],
},
],
},
};
适时切换路径与 Data URL 载入的方式
前面有提到大图片还是比较合适使用路径的引入方式,那如果我们想要依照图片的大小改变引入的方式要怎么做呢?为解决此问题,url-loader
让我们可以用档案大小决定要使用的 Loaders ,我们可以设定 url-loader
选项中的limit
,当档案大小超过这个数值时,预设会使用 file-loader
做处理:
// ./demos/load-image-by-url/webpack.config.js
module.exports = {
mode: "none",
module: {
rules: [
{
test: /\.png$/,
use: [
{
loader: "url-loader",
options: {
limit: 10240,
},
},
],
},
],
},
};
limit
的单位是 bytes
,上面的设定在 10 KB 以上的图片会由 file-loader
做处理。
读者可以变化 limit
的大小观察同张图片不同的输出情形,以了解不同载入方式的变化。
使用 svg-inline-loader
可以帮助我们在 HTML 中嵌入 SVG
SVG 格式的档案与一般图片不同,它们可以被视为合法的 HTML tag ,因此我们可以直接将其内容嵌入 HTML 中。
npm install svg-inline-loader -D
// ./demos/load-svg/webpack.config.js
module.exports = {
mode: "none",
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: "svg-inline-loader",
},
],
},
],
},
};
因为建置出来的模组会变为 HTML 代码,因此要修改嵌入方式:
// ./demos/load-svg/src/index.js
import WebpackLogo from "./webpack-logo.svg";
document.body.innerHTML = WebpackLogo;
直接将 SVG 的内容使用 innerHTML
填进 body
中就可以了。
Loader | 使用时机 |
---|---|
file-loader | 引入的图片大小较大时 |
url-loader | 引入的图片大小较小时,像是 Icon 等小图示 |
svg-inline-loader | 载入的图片为 SVG 格式时 |
一键下载
npm install file-loader url-loader svg-inline-loader -D
小声说
点赞是不要钱的,但作者会开心好几天~
下期讲生产环境搭建一条龙,生产环境配置是实际工作中必不可少的环节,下期见~
转载自:https://juejin.cn/post/7110949772520849445