- 配置篇详解
const HtmlWebpackPlugin = require('html-webpack-plugin')
const workbox = require('workbox-webpack-plugin')
const path = require('path')
// 打包后的文件访问路径: http://[devServer.host]:[devServer.port]/[output.publicPath]/[output.filename]
module.exports = {
mode: 'development',
// jquery模块将不参与打包,而是运行时在从外部引入
//以下配置使用时,就会变成 const jq = this['$'] ......
externalsType: 'this', // 'var' --> const jq = $
externals: {
jquery: '$',
}
// 多入口打包,会生成多个js文件插入html模版中
//dependOn: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。
// filename: 指定要输出的文件名称。
//import: 启动时需加载的模块。
//library: 指定 library 选项,为当前 entry 构建一个 library。
//runtime:一般用不上, 运行时 chunk 的名字。如果设置了,就会创建一个新的运行时 chunk。在 webpack 5.43.0 之后可将其设为 false 以避免一个新的运行时 chunk。
//publicPath: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 url 地址前缀。
entry: {
print: './src/print.js', //['print.js','print.css']
index: './src/index.js', //['index.js', 'index.css']
},
// 打包文件输出配置
output: {
path: path.resolve(__dirname, 'dist'),
filename: `[name].[chunkhash].js`, // [name]---和入口配置的名称一致 , [chunkhash]-- 文件hash,未改变的文件,后续的hash在打包后不会更改,浏览器请求资源时,能够从缓存中获取到,而无需加载服务器资源,节省性能消耗
// 清楚前次打包文件
clean: true,
// 将类型为 asset | asset/resource匹配文件打包输送到dist目录下的images目录下,同下方generator
assetModuleFilename: 'images/[hash][ext][query]',
},
module: {
rules: [
// asset/inline --- 文件都将作为 data URI 注入到 bundle 中
// asset/resource -- 文件件都将被发送到输出目录,并且其路径将被注入到 bundle 中
// asset/source -- 文件将原样注入到 bundle 中
{
test: /\.css$/i, // 匹配以.css结尾的文件(i不区分大小写)
// include: path.resolve(__dirname, 'src'), // 只将src下的css文件使用加载器
// exclude: /node_modules/, // 刨除以下文件
use: ['style-loader', 'css-loader'] // 使用的loader加载器,从右向左依次执行,右边解析完,将结果管道传输给左边,接着解析
},
{
test: /\.(png|jpg)$/i,// 匹配以.png或.jpg结尾的文件(i不区分大小写)
//asset/resource--- 所有匹配的图片都会被发送到打包后的文件夹内,并且其路径将被注入到 bundle 中
// [hash][ext][query]---> 打包后的名字
type: 'asset/resource', // 本地资源
// 将类型为 asset | asset/resource匹配文件打包输送到dist目录下的static目录下
// generator: {
// filename: 'static/[hash][ext][query]'
// }
},
{
test: /\.svg/,
type: 'asset/inline',
generator: {
// 默认是Base64编码,可用此方法自定义编码
dataUrl: content => {
content = content.toString();
return svgToMiniDataURI(content);
}
}
},
// {
// test: /\.txt/,
// type: 'asset/source',
// //bundle文件中这样: var _demo_txt__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./demo.txt */ \"./src/demo.txt\");
// }
{
test: /\.txt/,
type: 'asset', // 通用类型 默认小于8kb使用inline,不然使用resource
parser: {
// 通过此处改变默认的8kb判断
dataUrlCondition: {
maxSize: 4 * 1024 // 4kb
}
}
}
// 将/src/index.js文件中的this指向改为window,不然一般默认指向的是module.exports
// {
// test: require.resolve('./src/index.js'),
// use: 'imports-loader?wrapper=window',
// },
]
},
// 插件
plugins: [
// 根据哪个模版编译打包
new HtmlWebpackPlugin({
template: './index.html',
title: '测试啦'
}),
// 离线配置
new workbox.GenerateSW({
// 这些选项帮助快速启用 ServiceWorkers
// 不允许遗留任何“旧的” ServiceWorkers
skipWaiting: true,
clientsClaim: true
}),
// 这可以帮助我们在代码中安全地使用环境变量
// 代码中会有一个环境变量process.env.ASSET_PATH 指向 JSON.stringify(ASSET_PATH),
// new webpack.DefinePlugin({
// 'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
// }),
// 将一些模块依赖变更为全局变量依赖
// 在任何位置都可以通过_,join直接调用
// 打包时只要遇到,就会把对应的依赖引入进来
// new webpack.ProvidePlugin({
// _: 'lodash',
// join: ['lodash', 'join'],
// }),
],
optimization: {
// runtimeChunk: 'single',
splitChunks: {
// 缓存组
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
// output: {
// path: path.resolve(__dirname, 'dist'),
// filename: 'index.bundle.js',
// library: 'changeTest', // 将打包后为入口文件暴露出来的库名,被引入时,可以使用changeTest.方法调用
// libraryTarget: 'umd' // 配置此行,既可以被除script标签外,其他方式引入,例如import,require等
// },
// // 打包忽略以下的模块依赖,默认这些依赖,使用者本地已有且可以使用,减小打包体积,优化性能
// externals: [
// 'library/one',
// 'library/two',
// // 匹配以 "library/" 开始的所有依赖
// /^library\/.+$/,
// ],
// 工具
// devtool: 'inline-source-map',
}
-
一些有用的小功能点
-
全局exports
const file = 'blah.txt'; const helpers = { test: function () { console.log('test something'); }, parse: function () { console.log('parse something'); }, };
module: { rules: [ { test: require.resolve('./src/index.js'), use: 'imports-loader?wrapper=window', }, // 如此设置后,既可以在想要引入的文件位置,通过const { file, parse } = require('./globals.js')引入 { test: require.resolve('./src/globals.js'), use: 'exports-loader?type=commonjs&exports=file,multiple|helpers.parse|parse', }, ], },
-
Worker – 开启多进程
const worker = new Worker(new URL('./print.js', import.meta.url));
-
-
一些有用的小插件
-
webpack-merge
const { merge } = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'production', }); // package.json 中使用 webpack -- config webpack.pro.js
-
html-webpack-plugin
plugins: [ // 根据哪个模版编译打包 new HtmlWebpackPlugin({ template: './index.html', title: '测试啦' }) ],
-
http-server 搭配 workbox-webpack-plugin
//一些前置操作 // webpack.config.js -plugins中配置 new WorkboxPlugin.GenerateSW({ // 这些选项帮助快速启用 ServiceWorkers // 不允许遗留任何“旧的” ServiceWorkers clientsClaim: true, skipWaiting: true, }) // navigator --- 浏览器对象 // navigator.userAgent: 当前浏览器的用户代理字符串。 // navigator.appName: 当前浏览器的名称。 // navigator.appVersion: 当前浏览器的版本号。 // navigator.language:当前浏览器的语言设置。 // navigator.platform: 当前浏览器所在设备的操作系统平台。 // navigator.geolocation: 提供了一组 API,获取当前设备的地理位置信息。 // navigator.mediaDevices: 提供了一组 API,访问当前设备的音频、视频、屏幕等媒体设备。 // navigator.serviceWorker: 提供了一组 API,在浏览器中注册和管理 Service Worker,实现离线缓存和推送通知等功能。 // 入口文件中配置 if ('serviceWorker' in navigator) { // key in object --->返回Boolean window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js') .then(registration => { console.log('SW registered: ', registration); }) .catch(registrationError => { console.log('SW registration failed: ', registrationError); }) }) } 步骤: //1.先将项目打包2.运行"http-server dist" ,dist为打包后的文件夹,既可运行项目 "start": "http-server dist" //按照以上操作,既可实现一个离线的web项目 //注意:需要在localhost中查看才行,ip地址看不到log信息,离线应用也仅在localhost中维持。 // 注销方法:navigator.serviceWorker.getRegistrations().then((registrations=> { registrations.forEach(sw => sw.unregister())})
-
注: