开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
1.1
1.1.1 为什么使用webpack
-
1.1.2 作用域问题
(function () {
var nickname = "Tom";
})();
console.log(nickname); // Uncaught ReferenceError: nickname is not defined
var result = (function () {
var nickname2 = "Jack";
return nickname2;
})();
console.log(result); // Jack
1.1.3 ESM、CJS
CJS
: CommonJS
CJS
是同步导入模块CJS
不能在浏览器中工作。它必须经过转换和打包。- 命名导出
module.exports.sum = (x, y) => x + y; // 导出
const {sum} = require('./util.js'); // 导入
console.log(sum(2, 4));
- 默认导出
module.exports = (x, y) => x + y;
const sum = require('./util.js');
console.log(sum(2, 4));
ESM
: ES Modules
- 在很多现代浏览器可以使用(不是所有的浏览器都支持)
- 在浏览器使用时,修改
script
标签type
- 命名导出
export const sum = (x, y) => x + y;
import {sum} from './util.js'
console.log(sum(2, 4));
- 默认导出
export const sum = (x, y) => x + y;
import {sum} from './util.js'
console.log(sum(2, 4));
- 在浏览器使用
<script type="module">
import { func1 } from 'util';
func1();
</script>
1.2
1.2.1 安装webpack
- 必须安装
nodejs
:https://nodejs.org/zh-cn/
- 安装
webpack
:npm i webpack webpack-cli --save-dev
不建议全局安装 webpack -v
检查是否安装成功
1.2.2 运行webpack
npx webpack
1.2.3 配置webpack
- 根目录下新建一个配置文件
webpack.config.js
const path = require("path");
module.exports = {
mode: "development", // 模式
entry: "./src/index.js", // 打包入口地址
output: {
filename: "bundle.js", // 输出文件名
path: path.join(__dirname, "dist"), // 输出文件目录
},
};
提示:The 'mode' option has not been set,...意思是,没有配置mode(模式),提示配置一下
1.3
1.3.1 插件
- 插件(Plugin)可以贯穿 Webpack 打包的生命周期,执行不同的任务
https://webpack.docschina.org/concepts/#plugins
1.3.1 HtmlWebpackPlugin
- 安装
npm install --save-dev html-webpack-plugin
- 文档
https://github.com/jantimon/html-webpack-plugin
- 修改
webpack.config.js
配置
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development", // 模式
entry: "./src/index.js", // 打包入口地址
output: {
filename: "bundle.js", // 输出文件名
path: path.join(__dirname, "dist"), // 输出文件目录
},
plugins: [
new HtmlWebpackPlugin({
title: "管理输出", // 输出html的title, 指定template时不生效
template: "./index.html", // 基于哪个文件生成html
filename: "app.html", // 生成的html文件名
inject: "body", // script标签生成到哪里
}),
],
};
1.3.2 清理dist
/dist
文件夹会遗留了之前文件clean: true
清理/dist
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development", // 模式
entry: "./src/index.js", // 打包入口地址
output: {
filename: "bundle.js", // 输出文件名
path: path.join(__dirname, "dist"), // 输出文件目录
clean: true, // 清理dist
},
plugins: [
new HtmlWebpackPlugin({
title: "管理输出", // 输出html的title, 指定template时不生效
template: "./index.html", // 基于哪个文件生成html
filename: "app.html", // 生成的html文件名
inject: "body", // script标签生成到哪里
}),
],
};
1.4
1.4.1 mode
模式
development
开发模式,打包更加快速,省了代码优化步骤production
生产模式,打包比较慢,会开启 tree-shaking 和 压缩代码none
不使用任何默认优化选项
1.4.2 source map
当 webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置。
devtool: 'inline-source-map'
解决,浏览器控制台报错更友好
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development", // 模式
entry: "./src/index.js", // 打包入口地址
output: {
filename: "bundle.js", // 输出文件名
path: path.join(__dirname, "dist"), // 输出文件目录
clean: true, // 清理dist
},
devtool: "inline-source-map",
plugins: [
new HtmlWebpackPlugin({
title: "管理输出", // 输出html的title, 指定template时不生效
template: "./index.html", // 基于哪个文件生成html
filename: "app.html", // 生成的html文件名
inject: "body", // script标签生成到哪里
}),
],
};
1.4.3 watch mode
npx webpack --watch
保存文件,自动编译打包
1.4.4 webpack-dev-server
- 安装:
npm i webpack-dev-server -D
- 文档:
https://github.com/webpack/webpack-dev-server
-
- 提供了一个基本的
web server
- 具有
live reloading
(实时重新加载) 功能
- 提供了一个基本的
修改 webpack.config.js
配置
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development", // 模式
entry: "./src/index.js", // 打包入口地址
output: {
filename: "bundle.js", // 输出文件名
path: path.join(__dirname, "dist"), // 输出文件目录
clean: true,
},
devtool: "inline-source-map",
devServer: {
static: "./dist",
},
plugins: [
new HtmlWebpackPlugin({
title: "管理输出", // 输出html的title, 指定template时不生效
template: "./index.html", // 基于哪个文件生成html
filename: "app.html", // 生成的html文件名
inject: "body", // script标签生成到哪里
}),
],
};
运行 npx webpack-dev-server
cyq@caiyongqingdeMacBook-Air webpack-test % npx webpack-dev-server
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.3.120:8080/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::1]:8080/
<i> [webpack-dev-server] Content not from webpack is served from './dist' directory
asset bundle.js 570 KiB [emitted] (name: main)
asset app.html 309 bytes [emitted]
runtime modules 27.3 KiB 12 modules
modules by path ./node_modules/ 160 KiB
modules by path ./node_modules/webpack-dev-server/client/ 55.8 KiB 12 modules
modules by path ./node_modules/webpack/hot/*.js 4.3 KiB
./node_modules/webpack/hot/dev-server.js 1.59 KiB [built] [code generated]
./node_modules/webpack/hot/log.js 1.34 KiB [built] [code generated]
+ 2 modules
modules by path ./node_modules/html-entities/lib/*.js 81.3 KiB
./node_modules/html-entities/lib/index.js 7.74 KiB [built] [code generated]
./node_modules/html-entities/lib/named-references.js 72.7 KiB [built] [code generated]
+ 2 modules
./node_modules/ansi-html-community/index.js 4.16 KiB [built] [code generated]
./node_modules/events/events.js 14.5 KiB [built] [code generated]
./src/index.js 49 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 226 ms
webpack-dev-server
热更新功能 可以让页面自动刷新行
遇到问题
WARNING in asset size limit: The following asset(s) exceed the recommended size limit (293 KiB).
This can impact web performance.
Assets:
bundle.js (585 KiB)
WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (488 KiB). This can impact web performance.
Entrypoints:
main (586 KiB)
bundle.js
styles/af02acdb4a0028ac0250.css
WARNING in webpack performance recommendations:
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/
module.exports = {
//...
performance: {
hints:'warning',
//入口起点的最大体积
maxEntrypointSize: 50000000,
//生成文件的最大体积
maxAssetSize: 30000000,
//只给出 js 文件的性能提示
assetFilter: function(assetFilename) {
return assetFilename.endsWith('.js');
}
},
}
1.5 Asset Modules
1.5.1 resource
资源
- 配置
module
修改 webpack.config.js
配置
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development", // 模式
entry: "./src/index.js", // 打包入口地址
output: {
filename: "bundle.js", // 输出文件名
path: path.join(__dirname, "dist"), // 输出文件目录
clean: true,
},
devtool: "inline-source-map",
devServer: {
static: "./dist",
},
plugins: [
new HtmlWebpackPlugin({
title: "管理输出", // 输出html的title, 指定template时不生效
template: "./index.html", // 基于哪个文件生成html
filename: "app.html", // 生成的html文件名
inject: "body", // script标签生成到哪里
}),
],
module: {
rules: [
{
test: /.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/resource",
},
],
},
};
js
文件
import imgSrc from "../asset/logo.png";
// const a = 123;
// console.log(a);
let imgEle = document.createElement('img')
imgEle.src = imgSrc
document.body.appendChild(imgEle)
配置打包路径和文件名
- 1
output: {
filename: "bundle.js", // 输出文件名
path: path.join(__dirname, "dist"), // 输出文件目录
clean: true,
assetModuleFilename: "images/[contenthash][ext]", // 配置名字和扩展名
}
- 2
rules: [
//...
{
test: /.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/resource",
generator: {
filename: "images/[contenthash][ext]",
},
},
],
generator
的优先级大于output
1.5.2 inline
资源
当使用asset/inline
时,打包的资源不会单独生成打包文件。
比如图片,会转成base64
格式
rules: [
//...
{
test: /.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/inline",
},
],
1.5.3 source
资源
source
资源导出资源的源代码
rules: [
//...
{
test: /.txt$/,
type: "asset/source",
},
],
1.5.4 asset
通用类型
- 通过判断选择 加载类型 (生成data URI 还是生成单独的文件)
rules: [
{
test: /.(png|svg|jpg|jpeg|gif)$/i,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 1024 * 10, // 大于这个值就生成单独的文件
},
},
},
],