Loading... <div class="tip share">请注意,本文编写于 568 天前,最后修改于 568 天前,其中某些信息可能已经过时。</div> > 本篇博客仅适用未了解过或者没入门过 webpack 的小伙伴作为入门级的了解。 # 介绍 **webpack是一个现代的JavaScript应用的静态模块打包工具。** > 随着 SPA 单页应用的发展,使用的 js/css/png 等静态资源较多且难以管理,文件夹结构也容易混乱。很多时候我们希望项目可以具备压缩css,js 正确地处理各种 js/css 的 import 以及相关的模板 html 文件。 > > webpack 的出现就解决了这个难题。 在官网首页就有这样一张图,**bundle your assets**  > 本质上,**webpack** 是一个用于现代 JavaScript 应用程序的_静态模块打包工具_。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 *bundle*。 # 安装 **全局安装** ```bash npm install webpack -g ``` 安装完可以用命令行 `webpack -h` 查看。 **单独安装** 通常我们会将 Webpack 安装到项目的依赖中,这样就可以使用项目本地版本的 Webpack。 ```bash # 进入项目目录 # 确定已经有 package.json,没有就通过 npm init 创建 npm init # 安装 webpack 依赖 npm install webpack --save-dev ``` # 核心概念 在开始前你需要先理解一些__核心概念__: - 入口(entry) - 输出(output) - loader - 插件(plugin) - 模式(mode) - 浏览器兼容性(browser compatibility) - 环境(environment) --- 一个非常重要的知识: **webpack 开箱即用,可以无需使用任何配置文件。然而,webpack 会假定项目的入口起点为 `src/index.js`,然后会在 `dist/main.js` 输出结果,并且在生产环境开启压缩和优化。通常你的项目还需要继续扩展此能力,为此你可以在项目根目录下创建一个 `webpack.config.js` 文件,然后 webpack 会自动使用它。** 还有一个快速生成符合项目要求的 webpack 配置文件的方法,在使用 webpack-cli 的 `init` 命令时,会在创建配置文件之前会询问你几个问题。 ```bash npx webpack-cli init ``` ## 入口(entry) > __入口起点(entry point)__指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。 > > 默认值是 `./src/index.js`,但你可以通过在 *webpack configuration* 中配置 `entry` 属性,来指定一个(或多个)不同的入口起点。 基本的单入口写法 **webpack.config.js** ```javascript module.exports = { entry: './path/to/my/entry/file.js' }; ``` 多入口甚至分离式写法,参考[官方文档](https://webpack.docschina.org/concepts/entry-points/)。 ## 输出(output) > **output** 属性告诉 webpack 在哪里输出它所创建的 *bundle*,以及如何命名这些文件。主要输出文件的默认值是 `./dist/main.js`,其他生成文件默认放置在 `./dist` 文件夹中。 > > 你可以通过在配置中指定一个 `output` 字段,来配置这些处理过程。 **webpack.config.js** ```javascript const path = require("path") const config = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.join(__dirname, "dist") } } module.exports = config ``` ## loader > loader 用于对模块的源代码进行转换。loader 可以使你在 `import` 或 "load(加载)" 模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的得力方式。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 `import` CSS文件 例如,你可以使用 loader 告诉 webpack 加载 CSS 文件,首先安装相对应的 loader: ```bash npm install --save-dev css-loader ``` 然后指示 webpack 对每个 `.css` 使用 [`css-loader`](https://webpack.docschina.org/loaders/css-loader) **webpack.config.js** ```javascript module.exports = { module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], }, ], }, }; ``` **应保证 loader 的先后顺序:[`'style-loader'`](https://webpack.docschina.org/loaders/style-loader) 在前,而 [`'css-loader'`](https://webpack.docschina.org/loaders/css-loader) 在后。如果不遵守此约定,webpack 可能会抛出错误。** `loader` 从右到左(或从下到上)**倒序执行**,`test` *// 正则匹配打包过程中的文件路径*,`use` *// 所用到的加载器-倒序执行* webpack 根据正则表达式,来确定应该查找哪些文件,并将其提供给指定的 loader。在这个示例中,所有以 `.css` 结尾的文件,都将被提供给 `style-loader` 和 `css-loader`。 完整示例 ``` │ package-lock.json │ package.json │ webpack.config.js │ ├─ src │ index.css | index.js ``` index.css ```css body { background: #b86060; } ``` index.js ```javascript import './index.css' console.log("Hello Webpack") ``` 安装对应的loader ```bash npm install --save-dev style-loader css-loader ``` **webpack.config.js** ```javascript const path = require("path") const config = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.join(__dirname, "dist") }, module: { rules: [ { test: /\.css$/i, use: ['style-loader', 'css-loader'] } ] } } module.exports = config ``` 执行打包 ```bash npm run build ``` 在 `dist` 文件夹下新建一个 `index.html`,引入编译后的 `js` 文件 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="./bundle.js"></script> </body> </html> ``` 在浏览器中打开该文件,可以看到之前写好的 `css` 背景颜色就生效了。 关于loader的[官方文档](https://webpack.docschina.org/loaders/) 关于管理资源篇的[官方文档](https://webpack.docschina.org/guides/asset-management/) ## plugin > __插件__是 webpack 的 支柱 功能。webpack 自身也是构建于你在 webpack 配置中用到的__相同的插件系统__之上!插件目的在于解决 **loader** 无法实现的__其他事__。由于__插件__可以携带参数/选项,你必须在 webpack 配置中,向 `plugins` 属性传入一个 `new` 实例。 **用法** 由于__插件__可以携带参数/选项,你必须在 webpack 配置中,向 `plugins` 属性传入一个 `new` 实例。 示例:使用html-webpack-plugin生成html模板 ```bash npm install --save-dev html-webpack-plugin ``` **webpack.config.js** `HtmlWebpackPlugin` 将生成一个 HTML 文件,并在其中使用 `script` 引入一个名为 `my-first-webpack.bundle.js` 的 JS 文件。 ```javascript const path = require("path") const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 const config = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.join(__dirname, "dist") }, module: { rules: [ { test: /\.css$/i, use: ['style-loader', 'css-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template: "hello.html", // 模板html filename: "index.html" // 生成的html文件名 }) ] } module.exports = config ``` 根目录/hello.html ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Hello 乐心湖</h1> </body> </html> ``` 运行编译 `npm run build` 在 `./dist`可以看到 `HtmlWebpackPlugin` 就将我们的模板给整成 `index.html` ,并且引入了 `entry-js` ## 模式(mode) > 通过选择 `development`, `production` 或 `none` 之中的一个,来设置 `mode` 参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 `production`。 只需在配置对象中提供 `mode` 选项: ```javascript module.exports = { mode: 'development' }; ``` 支持以下字符串值: | 选项 | 描述 | | :------------ | :----------------------------------------------------------- | | `development` | 会将 `DefinePlugin` 中 `process.env.NODE_ENV` 的值设置为 `development`. 为模块和 chunk 启用有效的名。 | | `production` | 会将 `DefinePlugin` 中 `process.env.NODE_ENV` 的值设置为 `production`。为模块和 chunk 启用确定性的混淆名称,`FlagDependencyUsagePlugin`,`FlagIncludedChunksPlugin`,`ModuleConcatenationPlugin`,`NoEmitOnErrorsPlugin` 和 `TerserPlugin` 。 | | `none` | 不使用任何默认优化选项 | 如果没有设置,webpack 会给 `mode` 的默认值设置为 `production`。 也就是说你可以在 `js` 中使用 ```javascript if(process.env.NODE_ENV === 'development'){ } ``` # 热更新 > 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块, 而无需完全刷新。本页面重点介绍其 **实现**。 **HMR** 不适用于生产环境,这意味着它应当用于开发环境。 ## 启用 HMR 安装 ```bash npm install webpack-dev-server --save-dev ``` **webpack.config.js** ``` devServer: { contentBase: './dist', // 热更新的目录 hot: true, // 开启 }, ``` package.json ```json "scripts": { "hot": "webpack serve" }, ``` 执行 `npm run hot` 在打印的日志中可以看到一个链接,默认是8080端口。  之后你修改 `css` `html` `js` 都会自动编译,不过有时候可能需要你手动刷新浏览器才看得到效果。 --- 关于 **Webpack** 其他厉害的技巧和知识建议查看[官方文档](https://webpack.docschina.org/guides/),本笔记大篇幅也是复制参考官方指南而写。 Last modification:January 24, 2021 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 如果觉得我的文章对你有用,请随意赞赏