一句话说明本文主要介绍什么
分享webpack 开发环境中都需要配置什么?
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"}
}
前面的例子虽然在修改档案后会更新浏览器,但如果只是一小部分的修改,就让整个网页重整,会消耗不必要的资源,因此 Dev Server 提供了模组热替换的功能,它能在不重整整个网页的情况下,更新一小部分的内容。
首先要开启 devServer.hot
:
/ ./demos/hmr/webpack.config.js---------------模组热替换-------------------------------
...
module.exports = {...devServer: {hot: true},...
}
@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
: 决定要如何引入 Polyfill* false
: 预设值,全部手动引入* 'entry'
: 在入口 .js
档中引入完整的core-js
,Babel 会依照环境配置取出对应的 Polyfill* 'usage'
: Babel 会侦测代码,以引入对应的 Polyfillcorejs
:指定 core-js
版本这里配置使用 usage
的方式自动引入 Polyfill 。使用 babel-loader
将 babel 引入 webpack 的建置流程中:
// ./demos/babel-webpack/webpack.config.js
module.exports = {module: {rules: [{test: /\.js$/,use: {loader: "babel-loader",},},],},
};
1.在真实的环境中,虽然 webpack 可以识别 ES2015 的语法,但是浏览器不一定懂,因此还是需要利用 Babel 做转换。2.Babel 本身不会做任何的转换,需要加上对应的 Plugins 才会有转换的动作,而 Preset 可以将多个 Plugins 包起来,依照目标环境做对应的转换。3.Plugins 只会转换语法,对于新的语意并不会转换,这时需要藉由 core-js
的 Polyfill 帮助做转换。4.使用 babel-loader 引入 Babel 至 webpack 的建置流程中,让我们在建置过程中享有 Babel 的功能。### 使用webpack处理Style
postcss
: PostCSS 的核心库,负责建置流程postcss-cli
: PostCSS 的 CLI 工具,供使用者使用 CLI 执行 PostCSS使用 postcss-preset-env 转换代码
:现在我们想要将拥有新语法的 .css
内容转为旧版本相容的语法,这时就可以藉由 PostCSS 的postcss-preset-env
Pluginnpm install postcss postcss-cli -D
npm install postcss-preset-env -D
cmd执行postcss src/style.css --dir dist --use postcss-preset-env
使用 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 变数的语法。
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 以处理 CSSmini-css-extract-plugin
产生独立的 style 档案html-webpack-plugin
自动引入 .js
与 .css
档案npm install postcss-loader css-loader mini-css-extract-plugin html-webpack-plugin -D
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()],
};
图片使用路径载入时会需要多一次的请求以取得资源,这对于大图片来说是可以接受的,但对于 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",},],},],},
};
前面有提到大图片还是比较合适使用路径的引入方式,那如果我们想要依照图片的大小改变引入的方式要怎么做呢?为解决此问题,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 中嵌入 SVGSVG 格式的档案与一般图片不同,它们可以被视为合法的 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
点赞是不要钱的,但作者会开心好几天~
下期讲生产环境搭建一条龙,生产环境配置是实际工作中必不可少的环节,下期见~