webpack 基础总结
WHAT IT IS?
webpack 是一个 静态的、 模块化的 打包工具,为现代 JavaScript 应用提供服务。
为什么说是静态的、模块化的?
webpack 将各种模块和资源 最终打包为 一个或多个静态文件,之后可以部署到静态服务器上执行; webpack 支持多种模块化规范,包括 commonJs、ES6 module、AMD、UMD等。
webpack 是怎么打包的,什么是 webpack 依赖图?
webpack 首先找到入口文件, 之后从入口文件开始,递归查找分析模块之间的依赖关系,构建一个完整的依赖图, 最后遍历依赖图,打包一个个模块, 在打包过程中,对不同类型的文件需要使用对应的 loader 来处理, 另外,plugin 也贯穿了构建的整个过程。
loader 和 plugin 的区别是什么?
loader 用于将特定的模块类型进行转换; plugin 用于更加广泛的任务,如打包优化、资源管理、环境变量注入等。
HOW TO USE?
入口和出口的配置
使用 entry 和 output,例如, path 为 目录,默认是生成一个 dist 文件夹,这里改为 bundle, path 需要为一个绝对路径,所以采用 path.resolve 来拼接。
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "./bundle"),
clean: true,
},
}
基本 loader 的使用
css / less / postcss
处理 css 文件,一般需要用到 css-loader 和 style-loader, 首先,使用 css-loader 来解析 css 文件,将其加入到构建依赖中,但是此时样式还不会生效; 之后,使用 style-loader,它是负责将 css 代码动态地注入到 HTML 页面中,从而使样式生效。 所以,配置如下:css-loader 写在后面,因为 从后向前 采用loader。
module.exports = {
//...
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader",
],
},
//...
]
}
那 postcss 是啥? postcss 是一个用 js 工具和插件 转换 css 代码的工具,不同于上述的 loader 我们可以对该 loader 进行一些选项配置, 如选择一些插件,如给 css 添加浏览器前缀的 autoprefixer、预设配置 postcss-preset-env等。 可以直接在 webpack 中配置,也可以单独创建一个 postcss.config.js 文件来配置。 方法一、直接配置(较麻烦)
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
],
},
},
},
],
},
],
},
};
方法二、单独文件配置(好)
module.exports = {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
],
};
资源模块 assetModule
webpack 有内置的资源模块 asset modules,可用于 字体、icons、图片等资源的处理。 asset modules 有 4 中模块类型:
asset / resource : 导出为一个单独的文件并导出 URL; asset / inline : 导出一个资源的 data URI,采用 base 64 编码并直接嵌入到文档中; asset / source: 导出资源的源代码; asset: 自动在 resource 和 inline 中选择,根据资源的大小 limit;
最常用的是前两种,asset综合了前两种, 可以自行设定 limit, 例如为 60kb, 对于小于 60kb 的图片,采用asset/inline; 对于大于 60kb 的图片,采用asset/resource;
module.exports = {
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
}
]
},
}
两种方式有什么区别?asset/inline VS resource? 对于较小的文件,适合采用 asset/inline ,因为这样可以减少文件数目,进而减少 http 请求次数; 而对于较大的文件,如果还采用 asset/inline 的话, 会使打包出来的文件过大,增加加载时间;
img/png/jep/jepg/gif/svg 等
图片资源为 asset modules, 无需另外安装 loader 即可打包,思考以下两个问题: 到底 inline 还是 resource? 设置一个 maxSize,低于这个大小的图片采用 inline。 另外,如何控制打包出来的文件的文件名? 可以使用 generotor:
[name]:原文件名 [hash:8]: 长度为 8 的随机hash值 [ext]:原后缀
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif)$/,
type: "asset",
generator: {
filename: "[name]_[hash:8][ext]",
},
parser: {
dataUrlCondition: {
maxSize: 20 * 1024, // 20kb
},
},
},
]
},
}
js 使用babel
将 js 文件中的 ES6+ 代码转换为向前兼容的代码, babel 和 postcss 一样,需要额外配置插件,如转换箭头函数、转换const、let等, 可以单独使用某个插件如 "@babel/plugin-transform-arrow-functions", 也可以直接使用 babel 预设的配置 "@babel/preset-env"。同样,可以直接在webpack.config中配置,也可以单独创建一个配置文件。 方法一、直接配置
module.exports = {
module: {
rules: [
{
test: /\.js$/i,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
],
},
]
},
}
方法二、单独设置 babel.config.js
module.exports = {
presets: ["@babel/preset-env"],
};
vue/ts
略
基本 plugin 的使用
clean
每次打包前将之前的文件清除
html-webpack-plugin
打包时会自动生成一个 html 文件,自动帮我们引用生成的 main.js 文件。 可以传入 title 参数,改变文档的标题; template 参数,用于手动选择模板文件,如 vue2 中需要生成一个 id 为 app 的 div 元素。
plugins: [
new HtmlWebpackPlugin({
title: "nohao,webpack",
template: "./index.html",
}),
],
define-plugin
DefinePlugin 是 webpack 内置的插件,用于创建全局变量, 注意当 value 为字符串时,会将其作为 js 代码执行,所以需要用两层引号或者JSON.stringify()
new DefinePlugin({
BASE_URL: JSON.stringify("./"),
// BASE_URL: "'./'",
}),
自带的全局变量有:process.env.NODE_ENV, 当为开发环境是,值为 development;当为生产环境是,值为 production.
resolve 资源解析
文件路径解析
常常遇到 import 的文件路径不带后缀,此时需要根据 extensions 列表查找是否有这些类型的文件。
module.exports = {
//...
resolve: {
extensions: ['.js', '.json', '.wasm'],
},
};
或者有时候文件路径为一个文件夹,需要根据 mainFiles 查找对应文件。
module.exports = {
//...
resolve: {
mainFiles: ['index'],
},
};
dev-server 使用
加快开发速度,可以使用webpack建立一个开发服务器, 使用dev-server,会将打包的代码存在内存中,而不是磁盘中,所以速度更快,
devServer 的配置:
hot:true,默认为true,表示开启热模块更新; open:true,默认为false,为true时自动打开浏览器; compress:true,默认为fasle,为静态文件开启 gzip compression; host: XXXX,设置主机地址,一般设置为 localhost 或者 127.0.0.1,也可以设置为 0.0.0.0,
热模块替换HMS
模块热替换(HMR - hot module replacement)功能会在应用程序运行过程中,替换、添加或删除模块,而无需重新加载整个页面。 例如在 main.js 中引入了一个模块 greeting.js, greeting.js 的内容为:
console.log("nihao");
// console.log("哦嗨哟");
没有配置好时,我们把第二行取消注释,页面会整个刷新, 但是开启HMS之后,同时在 main.js 中设置需要热更新的模块(accept):
import "./utils/greeting";
if (module.hot) {
module.hot.accept(["./utils/greeting", "./utils/add"], () => {
console.log("greeting module 热更新啦");
});
}
这下我们仅仅改变 greeting.js,页面就只会部分更新啦。
题外话:回环地址和0.0.0.0
127.0.0.1 是一个回环地址,当本机向 127.0.0.1 请求时,会在计算机内部路由回自身,直接通信。
0.0.0.0 ,当服务器将 host 设置为 0.0.0.0 时,服务器会监听本机所有网卡的IP地址,因此只要是和本机处于一个局域网的主机就可以通过 本机的ip地址 和 端口号 访问到网站。 举例:我在电脑上打开了一个devServer,设置为0.0.0.0:8888,电脑的ip地址为x1.x2.x3.x4, 那么我在手机浏览器上输入:http://x1.x2.x3.x4:8888 ,nice!访问到页面了!
转载自:https://juejin.cn/post/7283797053338615849