webpack介绍
webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。是一种前端构建工具。
webpack 五个核心概念
Entry
入口(Entry):指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。
Loader
Loader:让 webpack 能够去处理那些非 JS 的文件 / json资源,比如样式文件、图片文件(webpack 自身只理解 JS)
Plugins
插件(Plugins):可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩, 一直到重新定义环境中的变量等。
Mode
模式(Mode):指示 webpack 使用相应模式的配置。
- development:生产模式,能让代码在本地进行调试运行的环境
- production:能让代码在线上优化上线的运行环境。
Output
输出(Output):指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。
简单的webpack打包测试
打包js, json文件
import data from './demo.json'; // 引入非js,json资源,进行打包会报错,所以需要通过loader来使webpack可以打包非js,json的资源。 // import "./index.css"; console.log("=========", "我是index.js文件"); console.log(data) // webpack ./src/index.js -o ./build/built.js --mode=development // 打包js,json文件不会报错
结论:
- webpack能处理js/json资源,不能处理其他资源。
- 生产环境和开发环境都能将 es6 的模块化语法转换成浏览器能识别的语法。
- 生产环境会压缩打包的js代码。
让webpack支持css的打包
use 数组中 loader 执行顺序:从右到左,从下到上 依次执行
'style-loader', 创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效 。
'css-loader' ,将 css 文件变成 commonjs 模块加载 js 中,里面内容是样式字符串 。
// 处理css文件 { // 这里表示匹配的文件,都需要通过该loader转化。 test: /.css$/, // 需要使用到的loader,从后往前执行 use: [ // 创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效 。 'style-loader', // 将 css 文件变成 commonjs 模块加载 js 中,里面内容是样式字符串 。 'css-loader' ] },
让webpack支持sass的打包
注意:这里需要下载sass和sass-loader两个包,不然报‘cannot find module sass’
// 处理sass文件 { test: /.scss$/, use: [ 'style-loader', 'css-loader', 'sass-loader' ] }
让webpack支持打包html资源
安装插件 html-webpack-plugin。而且需要引入才能使用。
默认创建一个空的html文件,然后引入打包后的js文件。
如果想要指定html模板,需要传入template属性。指定模板的路径。
// 引入html打包插件 const HtmlWebpackPlugin = require('html-webpack-plugin'); plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ]
让webpack支持打包图片资源
在 webpack5+,以上方法已经过时了,webpack5 使用了“资源模块”来代替以上 loader。 官方是这样解释“资源模块”的。
资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。
- asset/resource: 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
- asset/inline: 导出一个资源的 data URI。之前通过使用 url-loader 实现。
- asset/source: 导出资源的源代码。之前通过使用 raw-loader 实现。
- asset: 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。 具体访问juejin.cn/post/697033…处理样式中图片的方式
问题:默认处理不了 html 中 img 图片
// 方式一 { test: /.(jpe?g|png|svg|gif)/i, type: 'asset/resource', }, // 方式二 // 这个是处理样式中引入的图片资源 { test: /.(png|gif|jpg|jpeg)/, use: [ { loader: "url-loader", options: { // 优点: 减少请求数量(减轻服务器压力) // 缺点:图片体积会更大(文件请求速度更慢) limit: 8 * 1024, // 指定图片最大多少时转为base64格式。就是小于这个就被转化 name: '[name].[hash:10].[ext]',// 重命名文件 outputPath: 'static/img',// 文件的输出位置 esModule: false, // 这里需要将esModule关闭,因为他与commonjs模块化冲突 } } ], type: 'javascript/auto' },
处理html中引入的图片
他的作用是处理html中的img,然后交给url-loader处理。
// 这个是处理html中引入的图片资源 { test: /.html$/, loader: 'html-loader' }
让webpack支持打包其他资源
file-loader
// 打包其他资源(除了 html/js/css 资源以外的资源) { // 排除 css/js/html 资源 exclude: /.(css|js|html|sass|json|png|gif|jpg|jpeg)$/, loader: 'file-loader', options: { name: '[hash:10].[ext]' } }
可是自己测试,如果引入字体图标。然后webpack会指定打包,不需要使用file-loader。
url-loader和file-loader的区别:前者是将非文本小文件转化为base64 URI。减少对服务器的请求。
开发环境中的完整配置
const { resolve } = require("path") // 引入html打包插件 const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: "./src/js/index.js", output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ // 处理css文件 { // 这里表示匹配的文件,都需要通过该loader转化。 test: /.css$/, // 需要使用到的loader,从后往前执行 use: [ // 创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效 。 'style-loader', // 将 css 文件变成 commonjs 模块加载 js 中,里面内容是样式字符串 。 'css-loader' ] }, // 处理sass文件 { test: /.(scss|sass)$/, use: ['style-loader', 'css-loader', 'sass-loader'], }, // 处理图片 方式一 // { // test: /.(jpe?g|png|svg|gif)/i, // type: 'asset/resource', // }, // 这个是处理样式中引入的图片资源 方式二 { test: /.(png|gif|jpg|jpeg)/, use: [ { loader: "url-loader", options: { limit: 8 * 1024, name: '[name].[hash:10].[ext]', outputPath: 'static/imgs', esModule: false, } } ], type: 'javascript/auto' }, // 这个是处理html中引入的图片资源 { test: /.html$/, loader: 'html-loader' }, // 打包其他资源(除了 html/js/css 资源以外的资源) { // 排除上面处理后的文件资源 exclude: /.(css|js|html|sass|json|png|gif|jpg|jpeg)$/, loader: 'file-loader', options: { name: '[hash:10].[ext]', outputPath: "static/others" } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ], // 使用的模式 mode: 'development', devServer: { // 项目构建后路径 。当我们在打包后的资源中,引入的文件中,未能在打包后的资源中找到,就会在contentBase指定的文件夹中查找。在开发阶段方便打包。不需要使用copyWebpackPlugin插件将资源复制到打包后的资源中。 contentBase: resolve(__dirname, 'build'), // 启动 gzip 压缩 compress: true, // 端口号 port: 3000, // 自动打开浏览器 open: true } }