webpack从基础概念到项目配置,涉及知识点较多,现将学习使用过程中遇到内容记录下来,方便以后速查。
Webpack是一个模块打包工具,在Webpack里一切文件皆模块。通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合的文件。Webpack专注构建模块化项目。
Webpack可以看作是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其他一些不能被浏览器直接运行的扩展语音(如:Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
Grunt/Gulp是一种能够优化前端开发流程的工具,而Webpack是一种模块化的解决方案。
Grunt/Gulp是基于任务和流(task和stream)的。类似jquery,找到一个(或一类)文件,对其做一系列的链式操作,更新流上的数据,整条链式操作构成了一个任务,多个任务就构成了整个Web的构建流程。
Webpack是基于入口的。Webpack会自动的递归解析入口所需要加载的所有资源文件,然后用不同的loader来处理不同的文件,用pulgin扩展Webpack功能。
Grunt/Gulp更像是后端开发者的思路,需要对整个流程了如指掌。Webpack更倾向于前端开发者的思路。
Webpack的运行流程是一个串行的过程,从启动到结束会依次执行以下步骤:
在以上过程中,Webpack会在特定的的时间点广播特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑。并且插件可以调用Webpack提供的api改变Webpack的运行结果。
为了使用tree shaking,需要满足以下条件:
这种方式是通过package.json的sideEffects属性来实现的。
{
"sideEffects": false
}
「副作用」的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个export或多个export。举例说明,例如polyfill,它影响全局作用域,并且通常不提供export。
注意,任何导入的文件都会受到tree shaking的影响。这意味着,如果在项目中使用类似css-loader并导入CSS文件,则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:
{
"sideEffects": ['*.css']
}
从 webpack 4 开始,也可以通过 "mode" 配置选项轻松切换到压缩输出,只需设置为 "production"。
也可以在命令行接口中使用--optimize-minimize标记,来使用UglifyjsPlugin。
code splitting的必要性
import _ from 'lodash';
webpack.common.js配置如下:
....
optimization: {
splitChunks: {
chunks: 'all'
}
}
....
配置后,会将公用类库进行打包,生成一个vendors~main.js文件。
function getComponent() {
return import('lodash').then(({ default: _ }) => {
var element = document.createElement('div');
element.innerHTML = _.join(['Clear', 'love'], '');
return element;
})
}
getComponent().then(element => {
document.body.appendChild(element);
})
webpack-dev-server使用内存来存储Webpack开发环境下打包的文件,并且可以使用模块热更新,它比传统的http服务对开发更加简单高效。
模块热更新是Webpack是的一个功能,它可以使得代码修改以后不需刷新浏览器就可以更新,是高级版的自动刷新浏览器。devServer通过hot属性可以控制模块热更替。
const webpack = require('webpack');
const path = require('path');
let env = process.env.NODE_ENV == "development" ? "development" : "production";
const config = {
mode: env,
devServer: {
hot:true
},
plugins: [
new webpack.HotModuleReplacementPlugin(), //热加载插件
]
}
module.exports = config;
"script": {
"start": "NODE_EVN=development webpack-dev-server --config webpack-devlop-config.js --hot"
}
Webpack的热更新有称为热替换(Hot Module Replacement),缩写为HMR。这个机制可以实现不刷新浏览器而将新变更的模块替换旧的模块。原来如下:
使用最新稳定版本的webpack、node、npm等,较新的版本更够建立更高效的模块树以及提高解析速度。
由于loader对文件的转换操作很耗时,所以需要让尽可能少的文件被loader处理。我们可以通过以下3方面优化loader配置:
// webpack.common.js
module: {
rules: [
{
test:/\.js$/,
//babel-loader支持缓存转换出的结果,通过cacheDirectory选项开启
loader:'babel-loader?cacheDirectory',
//只对项目根目录下的src 目录中的文件采用 babel-loader
include: [path.resolve('src')],
//排除 node_modules 目录下的文件,node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
exclude: path.resolve(__dirname, 'node_modules')
}
]
}
Webpack 4移除了CommonsChunkPlugin取而代之的是两个新的配置项optimization.splitChunks和optimization.runtimeChunk来简化代码分割的配置。
通过设置 optimization.splitChunks.chunks: "all" 来启动默认的代码分割配置项。
当满足如下条件时,webpack 会自动打包 chunks:
optimization: {
splitChunks: {
chunks: 'async', // all async initial 是否对异步代码进行的代码分割
minSize: 30000, // 引入模块大于30kb才进行代码分割
maxSize: 0, // 引入模块大于Xkb时,尝试对引入模块二次拆分引入
minChunks: 1, // 引入模块至被使用X次后才进行代码分割
maxAsyncRequests: 5, //
maxInitialRequests: 3,
automaticNameDelimiter: '~', // 模块间的连接符,默认为"~"
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10 // 优先级,越小优先级越高
},
default: { // 默认设置,可被重写
minChunks: 2,
priority: -20,
reuseExistingChunk: true // 如果本来已经把代码提取出来,则重用存在的而不是重新产生
}
}
}
}
减少编译的整体大小,以提高构建性能。尽量保持chunks小巧。
thread-loader可以将非常耗性能的loaders转存到worker pool中。
不要使用太多的workers,因为Node.js的runtime和loader有一定的启动开销。最小化workers和主进程间的模块传输。进程间通讯(IPC)是非常消耗资源的。
对于一些性能开销较大的loader之前可以添加cache-loader,启用持久化缓存。
使用package.json中的postinstall清楚缓存目录。
使用DllPlugin将更新不频繁的代码进行单独编译。这将改善引用程序的编译速度。即使它增加了构建过程的复杂度。
利用DllPlugin和DllReferencePlugin预编译资源模块, 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。
以下几步可以提高解析速度:
以下几个实用的工具通过在内存中进行代码的编译和资源的提供,但并不写入磁盘来提高性能:
需要注意在不同的devtool的设置,会导致不同的性能差异。
在大多数情况下,cheap-module-eval-source-map是最好的选择。
某些实用工具,plugins和loaders都只能在构建生产环境时才使用。例如,在开发时使用UglifyJsPlugin来压缩和修改代码是没有意义的。以下这些工具在开发中通常被排除在外:
webpack只会在文件系统中生成已更新的chunk。应当在生成入口chunk时,尽量减少入口chunk的体积,以提高性能。
不要为了非常小的性能增益,牺牲了你应用程序的质量!!请注意,在大多数情况下优化代码质量,比构建性能更重要。
当进行多个编译时,以下工具可以帮助到你:
项目中的preset/plugins数量最小化
node-sass中有个来自Node.js线程池的阻塞线程的bug。当使用thread-loader时,需要设置workParallelJobs: 2
用Webpack优化前端性能是指优化Webpack输出结果,让打包的结果在浏览器运行快速高效。
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({ use: ['css-loader'] }) // 提取出chunk中的css到单独的文件中
}
]
},
plugins: [
new ExtractTextPlugin({ filename: 'index.css' })
]
}
webpack 在前端工程中随处可见,当前流行的 vue, react, weex 等解决方案都推崇 webpack 作为打包工具。前端工具云集的时代,这是你值得选择的之一。
webpack是前端工程构建的一套工具,为什么一个程序称之为一套呢,是因为webpack其实是npm的一个模块,使用起来的话,这期间还需要很多其它模块来进行支持,所以我称之为一套工具。
本文从一个小Demo开始,通过不断增加功能来说明webpack的基本配置,只针对新手。webpack基本的配置就可以熟悉了,会引入loader,配置loader选项,会设置alias,会用plugins差不多。
Plugins是webpack的基础,我们都知道webpage的plugin是基于事件机制工作的,这样最大的好处是易于扩展。讲解如果扩展内置插件和其他插件,以及我们常用的Plugins插件
webpack技巧的总结:进度汇报、压缩、复数文件打包、分离app文件与第三方库文件、资源映射、输出css文件、开发模式、分析包的大小、更小的react项目、更小的Lodash、引入文件夹中所有文件、清除extract-text-webpack-plugin日志。
Webpack 作为目前最流行的前端构建工具之一,在 vue/react 等 Framework 的生态圈中都占据重要地位。在开发现代 Web 应用的过程中,Webpack 和我们的开发过程和发布过程都息息相关,如何改善 Webpack 构建打包的性能也关系到我们开发和发布部署的效率。
新版 Webpack 中我们所做的每一个更新目的都在于此,为了当大家在使用 Webpack 的时候敏捷连续毫无顿挫感。 webpack 4 进行构建性能测试,得出的结果非常有趣。结果很惊人,构建时间降低了 60%-98%!
Webpack 是一个现代 JavaScript 应用程序的模块打包器 (module bundler) 。当 Webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块
Tobias Koppers是一位自由软件开发者,家住德国纽伦堡。他因写出webpack这个已有数百万开发者使用的开源软件而名噪一时。他目前专注于JavaScript和开源项目。以下是我对他个人的专访,希望对大家有所启发。
本文讲述css-loader开启css模块功能之后,如何与引用的npm包中样式文件不产生冲突。比如antd-mobilenpm包的引入。在不做特殊处理的前提下,样式文件将会被转译成css module。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!