Webpack是一个现代化的JavaScript应用程序的模块打包工具,它可以将各种静态资源(包括JavaScript、CSS、图片、字体等)打包成一个或多个JavaScript文件,以便于在浏览器中加载和运行。Webpack具有强大的模块化支持,可以通过各种插件和loader扩展其功能,使得它成为JavaScript应用程序开发中不可或缺的工具之一。
npx webpack index.js
webpack会用默认配置对index.js进行处理,例如: 创建文件夹dist,index.js内容输出到dist/main.js 必须添加入口文件,npx webpack 则会报错。
npx webpack
webpack,默认以根目录下的webpack.config.js为配置文件,配置项如果添加了入口文件,就不需要npx webpack index.js显示指定入口文件了。 当然你也可以指定其他文件为配置文件,只需要npx webpack --config webpackConfig.js。
file-loader:(可作用于字体,图片,音频等多种文件)将文件打包至文件夹(会存在于文件)
url-loader:(可作用于字体,图片,音频等多种文件),与file-loader一致,是将文件打包成base64内联(不会存在文件)
sass-loader:解析scss,sass文件
postcss-loader:通过postcss插件,对css文件进行处理,比如autoprefixer,postcss-pxtorem
css-loader:解析css文件,参数 importLoaders => 用于配置「css-loader 作用于 @import 的资源之前」有多少个 loader。 参数 modules => 设置为true时,可以通过模块化引入css时,标签元素不会被模块化,但是所有被处理过后的都会变成独立的,无法全局引入css
style-loader:将css文件内容内联到style
npx webpack -w
根据webpack.config.js的配置,文件每次修改都会产生实际的修改后的文件,构建速度慢,而且需要手动刷新页面
webpack-dev-server
根据webpack.config.js的配置,文件每次修改都会在内存中产生文件,构建速度更快,不需要自己手动刷新页面
自己编写server
根据webpack.config.js的配置,文件每次修改都会在内存中产生文件,构建速度更快,需要手动刷新页面
jsconst webpack = require('webpack');
const middleware = require('webpack-dev-middleware');
const config=require('./webpack.config')
const compiler = webpack(config);
const express = require('express');
const app = express();
app.use(middleware(compiler, {}));
app.listen(3000, () => console.log('Example app listening on port 3000!'));
webpack-dev-server 手动监听热更新
js if (module.hot) {
module.hot.accept('./print.js', function() {
console.log('Accepting the updated printMe module!');
printMe();
})
}
只支持ES Module的模块引入(因为ES Module 是静态引入)可以摇走无用的代码
webpack4 mode模式为produciton的时候默认引入
jsoptimization: {
usedExports: true
}
package.json里面sideEffects字段:"sideEffects"
值为false的情况下所有文件的都会进行检测,最好别填,会有默认配置或者["@babel/polyfill","*.css"]可以忽略这些文件1.进行如下配置,将自动把用到的插件统一打成一个js
jsoptimization: {
splitChunks:{
chunks:'all'
}
}
jsimport _ from 'lodash'
import axios from 'axios'
lodash和axios都会被打包成vendords-main.js
2.import异步导入时,会自动分割模块代码分割,例如:
jsfunction get() {
return import(/* webpackChunkName: "lodash" */'lodash').then((s) => {
console.log(s.default.join(['a', 'b', 'c']))
})
}
get()
此时的lodash会被单独打成vendor~lodash.js,没有显示定义名字则为0.js。 如果异步用到的包,在插件里面有被使用到,则splitChunks会很智能的把相同模块的内容,打到vendords-main.js插件包里面去
3.如果定义了名字,所有的模块都会被打包成一个vendor.js(包括异步模块和插件)
jsoptimization: {
splitChunks: {
chunks: 'all',
name: 'vendor'
}
}
4.分包配置
jsconfig.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // 只打包初始时依赖的第三方
},
vant: {
name: 'chunk-vant', // 单独将 vant 拆包
priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
test: /[\\/]node_modules[\\/]vant[\\/]/
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // 可自定义拓展你的规则
minChunks: 3, // 最小公用次数
priority: 5,
reuseExistingChunk: true
}
}
})
它的作用是将包含chunks 映射关系的 list单独从 app.js里提取出来,因为每一个 chunk 的 id 基本都是基于内容 hash 出来的,所以你每次改动都会影响它,如果不将它提取出来的话,等于app.js每次都会改变。
jsconfig.optimization.runtimeChunk({
name:'manifest'
})
Preload 是一个声明式 fetch,可以强制浏览器在不阻塞 document 的 onload 事件的情况下请求资源。 Preload通常用于本页面要用到的关键资源,包括关键js、字体、css文件。Preload将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度。
Prefetch 告诉浏览器这个资源将来可能需要,但是什么时间加载这个资源是由浏览器来决定的。 也就是说prefetch通常用于加速下一次导航,而不是本次的。
可以在启动命令时设置环境变量,
json"scripts": {
"bundle": "webpack",
"dev": "webpack-dev-server --env.development",
"build":"webpack --env.production"
}
但是这种环境变量只有在配置文件里面使用函数导出才能被读取,
jsmodule.exports=(env)=>{
if(env.production){
console.log('生产环境')
}
return { }
}
process.env读取不到这样定义的变量,需要被读取到,使用cross-env
1.第三方模块打包,且生成包的映射关系
添加命令:
json"dll": "webpack --config ./dll/webpack.dll.js",
执行命令,生成dll.js和dll.json,生成的dll需要带hash,避免缓存。DllPlugin的name需要和library相同。
dll/webpack.dll.js
jsconst path=require('path')
const webpack=require('webpack')
module.exports={
mode:'production',
entry:{
dll:['axios','better-scroll','vue','vue-router','vuex']
},
output:{
filename:'chunk-[name].[chunkhash:8].js',
path:path.resolve(__dirname,'./'),
library:'[name]'
},
plugins:[
new webpack.DllPlugin({
name:'[name]',
path:path.resolve(__dirname,'./chunk-[name].manifest.json')
})
]
}
2.生产环境下,使用dll
jsconst webpack=require('webpack')
const path = require('path')
const AddAssetHtmlPlugin=require('add-asset-html-webpack-plugin')
new AddAssetHtmlPlugin({
filepath:path.resolve(__dirname, './dll/chunk-dll.*.js'),
outputPath:'js',
publicPath:`${publicPath}js`
}), //dll.js添加
new webpack.DllReferencePlugin({
manifest:path.resolve(__dirname, './dll/chunk-dll.manifest.json')
}) //dll 映射关系
navigator.serviceWorker只在HTTPS或者localhost生效
webpack配置
jsconst workBoxPlugin=require('workbox-webpack-plugin')
new workBoxPlugin.GenerateSW({
clientsClaim:true,
skipWaiting:true
})
main.js入口文件配置
jsif('serviceWorker' in navigator){
window.addEventListener('load',()=>{
navigator.serviceWorker.register('./service-worker.js').then((res)=>{
console.log('pwa success',res)
}).catch((err)=>{console.log('pwa error',err)})
})
}
workbox.setConfig({debug: false}); 关闭console log信息
本文作者:BARM
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!