https://www.cnblogs.com/tugenhua0707/p/4793265.html
https://blog.csdn.net/qq_35480270/article/details/88775849
https://blog.csdn.net/loveer0/article/details/82257929
https://zhuanlan.zhihu.com/p/150731200
https://segmentfault.com/a/1190000015883378
webpack打包原理
webpack性能优化
1、webpack打包原理
把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载。
2、webpack的优势
(1) webpack 是以 commonJS 的形式来书写脚本滴,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。
(2)能被模块化的不仅仅是 JS 了。
(3) 开发便捷,能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转base64等。
(4)扩展性强,插件机制完善
3、什么是loader,什么是plugin
loader用于加载某些资源文件。因为webpack本身只能打包common.js规范的js文件,对于其他资源如css,img等,是没有办法加载的,这时就需要对应的loader将资源转化,从而进行加载。
plugin用于扩展webpack的功能。不同于loader,plugin的功能更加丰富,比如压缩打包,优化,不只局限于资源的加载。
4、什么是bundle,什么是chunk,什么是module
bundle:是由webpack打包出来的文件
chunk:是指webpack在进行模块依赖分析的时候,代码分割出来的代码块
module:是开发中的单个模块
5、webpack 和 gulp 的区别?
webpack:
webpack是一个模块打包器,强调的是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源都看成是模块,通过loader和plugin对资源进行处理。
gulp:
gulp是一个前端自动化构建工具,强调的是前端开发的工作流程,可以通过配置一系列的task,第一task处理的事情(如代码压缩,合并,编译以及浏览器实时更新等)。然后定义这些执行顺序,来让glup执行这些task,从而构建项目的整个开发流程。自动化构建工具并不能把所有的模块打包到一起,也不能构建不同模块之间的依赖关系。
6、什么是模热更新?有什么优点?
模块热更新是webpack的一个功能,它可以使得代码修改之后,不用刷新浏览器就可以更新。在应用过程中替换添加删出模块,无需重新加载整个页面,是高级版的自动刷新浏览器。
优点:
只更新变更内容,以节省宝贵的开发时间。调整样式更加快速,几乎相当于在浏览器中更改样式
7、webpack-dev-server 和 http服务器的区别
webpack-dev-server使用内存来存储webpack开发环境下的打包文件,并且可以使用模块热更新,比传统的http服务对开发更加有效。
8、什么是长缓存?在webpack中如何做到长缓存优化?
浏览器在用户访问页面的时候,为了加快加载速度,会对用户访问的静态资源进行存储,但是每一次代码升级或者更新,都需要浏览器去下载新的代码,最方便和最简单的更新方式就是引入新的文件名称。
在webpack中,可以在output给出输出的文件制定chunkhash,并且分离经常更新的代码和框架代码,通过NameModulesPlugin或者HashedModulesPlugin使再次打包文件名不变。
9、什么是Tree-sharking?CSS可以Tree-shaking吗?
Tree-shaking是指在打包中去除那些引入了,但是在代码中没有被用到的那些死代码。在webpack中Tree-shaking是通过uglifySPlugin来Tree-shakingJS。Css需要使用Purify-CSS。
有关vue项目中,@默认src的问题
在Vue项目中,@符号默认指向src目录。
这是通过webpack
配置文件中的alias
别名来实现的。这样做的好处是可以更方便地引用src目录中的文件,而不需要使用相对路径。
在大多数情况下,@不需要额外手动配置,vue-cli会定义。
Vue CLI 在创建项目时会自动配置好这个别名。如果你使用的是 Vue CLI 创建的项目,那么默认情况下,@符号就会指向src目录。
但是,如果你使用的是手动配置的Vue项目,那么你可能需要在webpack
配置文件中手动添加这个别名。你可以在webpack
配置文件中的resolve.alias
中添加以下内容:
const path = require('path')
/**
* __dirname:当前文件夹所在的绝对路径
*/
const resolve = (dir) => path.join(__dirname, dir);//或 path.resolve(__dirname, dir)
module.exports = {
configureWebpack: {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
},
//或
chainWebpack: (config) => {
config.resolve.alias
.set("@", resolve("src"))
.set("@static", resolve("public/static"))
}
}
vue.config.js里chainWebpack和configureWebpack有什么区别
官网定义:
- configureWebpack:
如果这个值是一个对象,则会通过 webpack-merge
合并到最终的配置中。
如果这个值是一个函数,则会接收被解析的配置作为参数。该函数既可以修改配置并不返回任何东西,也可以返回一个被克隆或合并过的配置版本。
如果你需要基于环境有条件地配置行为,或者想要直接修改配置,那就换成一个函数 (该函数会在环境变量被设置之后懒执行)。该方法的第一个参数会收到已经解析好的配置。在函数内,你可以直接修改配置,或者返回一个将会被合并的对象。
configureWebpack
不支持 vue cli 的语法糖或者说是不支持链式编程配置形式。只能通过操作对象的形式,来修改默认的 webpack
配置。
configureWebpack 对象形式
configureWebpack: {
// 修改entry配置
entry: './src/main.js',
// 修改output配置
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
// 别名配置
alias: {
assets: "@/assets",
common: "@/common",
components: "@/components",
// 建议改成如下方式
'@assets': "@/assets",
'@common': "@/common",
'@components': "@/components",
},
},
},
configureWebpack 函数形式
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...
config.mode = 'production'
} else {
// 为生产环境修改配置...
config.mode = 'development'
}
// 开发生产共同配置别名
// 直接修改配置
config.resolve.alias['@assets'] = resolve('src/assets'),
//返回一个将要合并得对象
return{
resolve: {
alias: {
'@assets': resolve('src/assets'),
},
}
}
},
tips:
assets: "@/assets"
写法 在<img src="assets/logo.png" alt="">
中配置无效,具体原因可能是直接把assets当成了根路径,改为@assets: "@/assets"
即可。前面必须添加一个符合@,简单测试了一下,好像必须是@开头,类似$assets
写法,也不生效。
示例:
<!-- assets写法,在src中,不生效 -->
<img src="assets/logo.png" alt="">
<!-- 生效 -->
<img src="@assets/logo.png" alt="">
<home></home>
<script>
// 以下2种写法都生效
import home from "components/index.vue";
import home1 from "@components/index.vue";
</script>
- chainWebpack:
是一个函数,会接收一个基于 webpack-chain
的 ChainableConfig
实例。允许对内部的 webpack
配置进行更细粒度的修改。
Vue CLI 内部的 webpack
配置是通过 webpack-chain
维护的。这个库提供了一个 webpack
原始配置的上层抽象,使其可以定义具名的 loader
规则和具名插件。
你可以在vue.config.js
文件中使用chainWebpack
来添加、修改或删除webpack
配置。它提供了一种更灵活的方式来修改webpack
配置,可以在配置过程中进行更细粒度的控制。
例如,你可以使用chainWebpack
来添加一个新的loader或plugin。
例子:
chainWebpack: (config) => {
config.resolve.alias
.set("@", resolve("src"))
.set("@static", resolve("public/static"))
// 修改Loader选项
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
// 修改他的选项
return options
})
// 添加一个新的loader
config.module
.rule('custom-loader')
.test(/\.custom$/)
.use('custom-loader')
.loader('custom-loader')
.end();
// 替换一个规则里的Loader
const svgRule = config.module.rule('svg')
// 清除已有的loader。
// 如果你不这样做,接下来的loader会附加在该规则现有的 loader 之后。
svgRule.uses.clear()
// 添加要替换的 loader
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
.end();
}
参数说明:
name 是 webpack-chain 里的key,就是要加入的插件在 webpack-chain 配置里的 key ,就是我们自定义插件的名字,一般我们都保持跟插件名称相同。
WebpackPlugin 使用的 webpack 插件名,在这里,可以直接使用插件,无需进行实例化,就是不需要 new WebpackPlugin()
args 插件的参数信息。特别注意,args是一个数组,例如 [{},{}] 这种方式,可以配置多个插件实例。
tips:需要注意的是,这两个选项可以单独使用,也可以同时使用。如果同时使用,
configureWebpack
的配置会被合并到chainWebpack
的配置中。
无论是使用 chainWebpack
还是 configureWebpack
,都需要在vue.config.js
文件中进行配置,并且需要重新启动开发服务器或重新构建项目才能使配置生效。
webpack中的url-loader和file-loader的区别
webpack对png等图片静态资源打包用到的插件,对图片路径的处理方法常用的有两种,一种是file-loader
,一种是url-loader
。
简单点说url-loader
包含了file-loader
,通过限定一个图片的大小(limit),来判断是否采用编码的方式。小于limit的时候使用base64进行压缩,大于则使用file-loader
变成路径。
- file-loader
file-loader
将图片移动到dist目录(或者outputPath定义的目录)下并返回一个相对于dist的路径
rules: [
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'file-loader',
options: {
name: '[name]_[hash:6].[ext]',
outputPath: 'images/',
}
}
}
]
效果:
<img src="http://localhost:8080/asset/img/logo.png"
- url-loader
url-loader
包含了file-loader
,但 url-loader
不依赖于 file-loader
,相比file-loader
多了一个limit
配置项(1024 = 1kb),在超过limit
的时候执行和file-loader
相同的功能,当小于limit
时会将文件打包成base64
文件到js打包文件里,通过限定大小(limit),来判断是否采用编码的方式
rules: [
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash:6].[ext]',
outputPath: 'images/',
// url-loader的limit配置项
// 40kb 以下的文件采用 url-loader
limit: 1024*40
}
}
}
]
效果:
<img src="data:image/png;base64,...."
url-loader
会将图片转成base64文件放在打包js文件里,节约了一次HTTP请求,如果图片太大会导致加载慢(适合小图片)
最好两个不要放在一起,打包后可能产生未知问题。
loadURL 和 loadFile 的区别
这两者最大的区别是 loadURL 可以加载线上的资源地址而 loadFile 不能,两者都能加载本地的文件地址。
{
appId: "lethe.com",
productName: "my-project", // 项目名,也是生成的安装文件名,即wyDemo.exe
copyright: "lethe Copyright © 2022", // 版权信息
files: ["./main.js", "./dist"]
extraFiles: [
// 把指定的资源复制到程序根目录,即把server文件夹的内容复制到程序根目录,这里server文件夹下的内容相当于我的后台,我在background.js中有相应的处理。
"./server",
],
directories: {
output: "dists", // 输出文件路径
},
win: {
// win相关配置
// icon: "./favicon.ico", // 图标,当前图标在根目录下,注意这里有两个坑
requestedExecutionLevel: "requireAdministrator", //获取管理员权限
target: ["nsis", "zip"], // 利用nsis制作安装程序
},
nsis: {
oneClick: false, // 是否一键安装
allowElevation: true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
allowToChangeInstallationDirectory: true, // 允许修改安装目录
// installerIcon: "./favicon.ico", // 安装图标
// uninstallerIcon: "./favicon.ico", // 卸载图标
// installerHeaderIcon: "./favicon.ico", // 安装时头部图标
createDesktopShortcut: true, // 创建桌面图标
createStartMenuShortcut: true, // 创建开始菜单图标
shortcutName: "leDom", // 图标名称(项目名称)
},
}