15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > webpack打包详解

webpack打包详解

时间:2023-06-10 05:57:02 | 来源:网站运营

时间:2023-06-10 05:57:02 来源:网站运营

webpack打包详解:

一、Webpack 打包

1.1 webpack 概述

yarn webpack

1.2 webpack 配置

1.2.1 webpack 配置文件

const path = require("path")module.exports = { entry: "./src/index.js", // 指定打包的路径 output: { // 输出文件设置 filename: "bundle.js", // 文件名 path: path.join(__dirname, 'output') // 一定要是绝对路径 }}

1.2.2 webpack 工作模式

module.exports = { entry: "./src/index.js", // 指定打包的路径 output: { // 输出文件设置 filename: "bundle.js", // 文件名 path: path.join(__dirname, 'output') // 绝对路径 }, mode: "development" // 设置相关的执行模式}

1.2.3 webpack资源模块加载

const path = require("path")module.exports = { entry: "./src/main.css", // 指定打包的路径 output: { // 输出文件设置 filename: "bundle.js", // 文件名 path: path.join(__dirname, 'output') // 绝对路径 }, mode: "none", // 设置相关的执行模式 module: { rules: [ // 针对其他资源的配置 { test: /.css$/, // 匹配打包的文件路径 use: ["style-loader","css-loader" ] // 指定匹配到的文件需要执行的loader } ] }}

1.2.4 webpack导入资源模块

// main.jsimport creating from './header.js'import './main.css'const heading = creating()document.body.append(heading)// heading.jsimport "./heading.css"export default () => { const ele = document.createElement('h2') ele.textContent = "hello world" ele.classList.add("heading") ele.addEventListener("click", () => { alert("hello wepack") }) return ele}

1.2.5 webpack 文件资源加载器

const path = require("path")module.exports = { entry: "./src/index.js", // 指定打包的路径 output: { // 输出文件设置 filename: "bundle.js", // 文件名 path: path.join(__dirname, 'output'), // 绝对路径 publicPath: "output/" // 加载的路径 / 不能省略 }, mode: "none", // 设置相关的执行模式 module: { rules: [ // 针对其他资源的配置 { test: /.css$/, // 匹配打包的文件路径 use: ["style-loader","css-loader" ] // 指定匹配到的文件需要执行的loader }, { test: /.png$/, use: "file-loader" } ] }}

1.2.6 data URL加载器

{ test: /.png$/, use: { loader: "url-loader", options: { limit: 10 * 1024, esModule: false // 新版本file-loader的esModule属性默认是true } } }

1.2.7 加载器类型

1.2.8 Webpack 与 ES 2015

{ test: /.js$/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"] } } }

1.2.9 webpack加载资源的方式

css-laoder加载资源的两种方式

@import url(./heading.css); /* 加载资源样式 */body { color: greenyellow; background-image: url(./icon.png); /* 先进行css-loader 发现其他格式的就交给其他格式的loader转化 */ background-size: cover;}html加载资源,比如image标签的src,不过需要先配置html-loader

{ test: /.html$/, use: { loader: 'html-loader', // 默认只会处理image标签的src属性 options: { atts: ['img:src', 'a:href'] // 手动设置加载的标签和标签属性,需要html-loader是0.5.5版本 } }}

1.2.10 webpack核心工作原理

1.2.11 开发一个 loader

两种方法

其实loader就是管道

const marked = require("marked")module.exports = sourse => { const html = marked(sourse) // return `export default (${JSON.stringify(html)})` // 直接返回输出的字符串, // 还可以 返回 html 字符串,交给下一个loader操作 return html}

1.3 webpack常用插件

1.3.1 自动清除插入目录插件

const { CleanWebpackPlugin } = require("clean-webpack-plugin") // 导入插件module.exports = { plugins: [ // 配置插件的位置 new CleanWebpackPlugin() // 创建实例并且放到plugins数组中 ]}

1.3.2 自动生成使用打包结果的html

// plugins 数组中的设置new HtmlWebpackPlugin({ title: "webpack plugin sample", // 设置html文件的title主体 meta: { viewport: "width=device-width" // 视口宽度 }, template: "./src/index.html" // 参照的模板 })./src/index.html

<h1><%= htmlWebpackPlugin.options.title %></h1>new HtmlWebpackPlugin({ filename: "about.html" })

1.3.3 静态资源打包器

new copyWebpackPlugin({ // 实例 copy插件 设置对象 patterns: [ // 设置地址 "public" // 指定的文件目录 ] })

1.3.4 开发一个插件







class myPlugin { apply (compliter) { console.log("启动"); compliter.hooks.emit.tap("mypl", compilation => { // 注册函数,emit是输出文件前的事件挂载点 // compilitation 可以理解为此次打包的上下文,打包产生的过程中产生的结果都在这个数据中 for (const name in compilation.assets) { // console.log(name); // 获取文件名 // console.log(compilation.assets[name].source()); // 获取文件内容 if (name.endsWith(".js")) { const contents = compilation.assets[name].source() const withComment = contents.replace(////*/*+///g, "") compilation.assets[name] = { source: () => withComment, // source 是将来要操作的数据 size: () => withComment.length // size 是必需的 } } } }) }}

1.4 webpack 提升开发体验

  1. 提供source Map 支持

1.4.1 实现自动编译

yarn webpack --watch

1.4.2 实现自动刷新

yarn webpack-dev-server --open

1.4.3 webpack Dev Server 静态资源访问

module.exports = { devServer: { contentBase: ["public"] // 配置静态路径,可以是数组、字符串 } }

1.4.4 webpack Dev Server 代理API服务

devServer: { contentBase: ["public"], // 配置静态路径,可以是数组、字符串 proxy: { // 用于配置代理的配置 "/api": { // 代理的请求路径前缀 // http://localhost:8080/api/user 相对于 https://api.github.com/api/user, 所有需要重写 target: "https://api.github.com", // 代理的目标 pathRewrite: { // 代理路径的重写 // http://localhost:8080/api/user 相对于 https://api.github.com/user "^/api": "" // 将代理到的路径中以 /api 开头的路由替换为空 }, // 默认为 false 不能使用 localhost:8080 作为请求 gitHub 主机名 changeOrigin: true // true 会以实际代理的主机名进行请求 } } }

1.5 Source Map

1.5.1 源代码地图

1.5.2 webpack 配置 Source Map

devtool: "source-map" // 开发中配置的辅助工具

1.5.3 eval 模式

devtool: "eval"const HtmlWebpackPlugin = require("html-webpack-plugin")const allModes = [ 'eval', 'cheap-eval-source-map', 'cheap-module-eval-source-map', 'eval-source-map', 'cheap-source-map', 'cheap-module-source-map', 'inline-cheap-source-map', 'inline-cheap-module-source-map', 'source-map', 'inline-source-map', 'hidden-source-map', 'nosources-source-map']module.exports = allModes.map(item => { return { mode: "none", devtool: item, entry: "./src/index.js", output: { filename: `js/${item}.js` }, module: { rules: [ { test: //.js$/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"] } } } ] }, plugins: [ new HtmlWebpackPlugin({ filename: `${item}.html` }) ] }})

1.6 webpack HMR

1.6.1 HMR开启

const webpack = require("webpack")module.exports = { …… devServer: { hot: true // 开启热加载 } plugins: [ new webpack.HotModuleReplacementPlugin() // 模块热加载插件 ]}

1.6.2 HMR API

let lastHeader = heading // 获取旧元素module.hot.accept("./header.js", () => { const value = lastHeader.innerHTML // 获取状态 document.body.remove(lastHeader) const newHeading = creating() newHeading.innerHTML = value // 将状态赋值给新的元素 document.body.append(newHeading) lastHeader = newHeading})import icon from "./icon.png"module.hot.accept("./icon.png", () => { img.src = icon console.log(icon);})

1.6.3 HMR 注意事项

// hot: true,hotOnly: true,

1.7 生产环境优化

1.7.1 不同环境下的配置

module.exports = (env, argv) => { // 环境名,运行过程中的所有参数 const config = { entry: "./src/index.js", // 指定打包的路径 output: { // 输出文件设置 filename: "js/bundle.js", // 文件名 path: path.join(__dirname, 'dist'), // 绝对路径 // publicPath: "dist/" // 加载的路径 / 不能省略 }, mode: "development", // 设置相关的执行模式 devtool: "eval", // 开发中配置的辅助工具 devServer: { hot: true, // hotOnly: true, contentBase: ["public"], // 配置静态路径,可以是数组、字符串 }, module: { rules: [ // 针对其他资源的配置 { test: //.css$/, use: ["style-loader", "css-loader"] }, { test: //.png/, use: { loader: "url-loader", options: { limit: 10 * 1024, esModule: false } } }, { test: //.js$/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"] } } } ] }, plugins: [ // 配置插件的位置 new HtmlWebpackPlugin({ title: "webpack plugin sample", // 设置html文件的title主体 meta: { viewport: "width=device-width" // 视口宽度 }, template: "./src/index.html" // 参照的模板 }), new webpack.HotModuleReplacementPlugin() ] } // 开发模式 if (env === "production") { config.mode = "production" config.devtool = false config.plugins = [ new CleanWebpackPlugin(), new CopyWebpackPlugin(['public']), ...config.plugins ] } return config}// webpack.prod.jsconst common = require("./webpack.common")const { merge } = require("webpack-merge")const { CleanWebpackPlugin } = require("clean-webpack-plugin")const CopyWebpackPlugin = require("copy-webpack-plugin");module.exports = merge(common, { // merge 类似于 assign(),但是merge可以用于重新改变值,并且是新的空间 mode: 'production', plugins: [ new CleanWebpackPlugin(), new CopyWebpackPlugin({ // 实例 copy插件 设置对象 patterns: [ // 设置地址 "public" // 指定的文件目录 ] }) ]})

1.7.2 definePlugin

const webpack = require("webpack")module.exports = { entry: "./src/main.js", output: { filename: "main.js", }, mode: "none", plugins: [ new webpack.DefinePlugin({ API : JSON.stringify("123456") }) ]}

1.8 代码优化配置—optimization

1.8.1 tree shaking (摇树)

const webpack = require("webpack")module.exports = { ……, optimization : { // 集中配置webpack内部优化功能 usedExports: true, // 只输出外部使用的成员 minimize: true // 开启压缩 }}

1.8.2 合并模块

module.exports = { ……, optimization : { // 集中配置webpack内部优化功能 usedExports: true, // 只输出外部使用的成员 concatenatemodules: true // 合并尽可能多的模块 }}

1.8.3 tree-shaking 与 babel

module.exports = { ……, rules: [ { test: //.js$/, use: { loader: "babel-loader", options: { presets: [ ["@babel/preset-env", { modules: false }] // 默认属性是modules属性默认值是auto,自动转换 ESM 插件是否开启 ] } } } ], ……}

1.8.4 sideEffects —副作用

// webpack.config.jsmodule.exports = { ……, optimization: { // 集中配置webpack内部优化功能 usedExports: true, // 只输出外部使用的成员 sideEffects: true, // 开启副作用插件 // minimize: true // 开启压缩 }}// package.json{ ……, "sideEffects": false // 是否有副作用}必须确保没有副作用才能用false

否则用数组标注有副作用的文件

// package.json{ ……, "sideEffects": ["./src/a.js", "./src/*.css"] // 有副作用的文件}

1.9 code splitting—代码分包

1.9.1 多入口打包

module.exports = { mode: 'none', entry: { index: './src/index.js', album: './src/album.js' }, output: { filename: '[name].bundle.js' // [name]会动态命名 }, ……, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'Multi Entry', template: './src/index.html', filename: 'index.html', chunks: ['index'] // 允许插入到模板中的chunks }), new HtmlWebpackPlugin({ title: 'Multi Entry', template: './src/album.html', filename: 'album.html', chunks: ['album'] }) ]}

1.9.2 提取公共模块

optimization: { splitChunks: { // 自动提取所有公共模块到单独 bundle chunks: 'all' } }

1.9.3 动态导入

const render = () => { const hash = window.location.hash || '#posts' const mainElement = document.querySelector('.main') mainElement.innerHTML = '' if (hash === "#post") { import("./posts/posts.js").then(({ default: posts }) => { // 获取成员 document.body.appendChild(posts) }) } else if (hash === "#album") { import("./album/album.js").then(({ default: album }) => { document.body.appendChild(album) }) }}

1.9.4 魔法注释

if (hash === "#post") { import(/*webpackChunkName: "auble" */"./posts/posts.js").then(({ default: posts }) => { document.body.appendChild(posts) }) } else if (hash === "#album") { import("./album/album.js").then(({ default: album }) => { document.body.appendChild(album) }) }





1.9.5 MiniCssExtractPlugin

const { CleanWebpackPlugin } = require('clean-webpack-plugin')const HtmlWebpackPlugin = require('html-webpack-plugin')const MiniCssExtractPlugin = require("mini-css-extract-plugin")module.exports = { mode: 'none', entry: { main: './src/index.js' }, output: { filename: '[name].bundle.js' }, module: { rules: [ { test: //.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader' ] } ] }, plugins: [ new CleanWebpackPlugin(), new MiniCssExtractPlugin({ linkType: 'text/css', }) ]}

1.9.6 optimize-css-assets-webpack-plugin

1.10 输出文件名hash

new MiniCssExtractPlugin({ filename: "[name]-[hash:8].bundle.css" // :num 限制位数 }

关键词:打包

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭