webpack是一个打包模块化javascript的工具,在webpack里一切文件皆模块,经过loader转换文件,经过plugin注入钩子,最后输出由多个模块组合成的文件,webpack专一构建模块化项目。
WebPack能够看作是模块打包机:它作的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
官网的图片形象的展现了webpack的定义
javascript
Webpack与Gulp、Grunt没有什么可比性,它能够看做模块打包机,经过分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。Gulp/Grunt是一种可以优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,不过Webpack的优势使得Webpack在不少场景下能够替代Gulp/Grunt类的工具。css
他们的工做方式也有较大区别:html
Grunt和Gulp的工做方式是:在一个配置文件中,指明对某些文件进行相似编译,组合,压缩等任务的具体步骤,工具以后能够自动替你完成这些任务。前端
Webpack的工做方式是:把你的项目当作一个总体,经过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的全部依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
三者都是前端构建工具,grunt和gulp在早期比较流行,如今webpack相对来讲比较主流,不过一些轻量化的任务仍是会用gulp来处理,好比单独打包CSS文件等。java
grunt和gulp是基于任务和流(Task、Stream)的。相似jQuery,找到一个(或一类)文件,对其作一系列链式操做,更新流上的数据, 整条链式操做构成了一个任务,多个任务就构成了整个web的构建流程。react
webpack是基于入口的。webpack会自动地递归解析入口所须要加载的全部资源文件,而后用不一样的Loader来处理不一样的文件,用Plugin来扩展webpack功能。jquery
从构建思路来讲
gulp和grunt须要开发者将整个前端构建过程拆分红多个Task
,并合理控制全部Task
的调用关系
webpack须要开发者找到入口,并须要清楚对于不一样的资源应该使用什么Loader作何种解析和加工webpack
对于知识背景来讲
gulp更像后端开发者的思路,须要对于整个流程了如指掌 webpack更倾向于前端开发者的思路es6
webpack的缺点是只能用于采用模块化开发的项目web
bundle:是由webpack打包出来的文件,
chunk:代码块,一个chunk由多个模块组合而成,用于代码的合并和分割。
module:是开发中的单个模块,在webpack的世界,一切皆模块,一个模块对应一个文件,webpack会从配置的entry中递归开始找出全部依赖的模块。
loader:模块转换器,用于将模块的原内容按照须要转成你想要的内容
plugin:在webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果,是用来自定义webpack打包过程的方式,一个插件是含有apply方法的一个对象,经过这个方法能够参与到整个webpack打包的各个流程(生命周期)。
模块热更新是webpack的一个功能,他可使得代码修改事后不用刷新浏览器就能够更新,是高级版的自动刷新浏览器。
devServer中经过hot属性能够空时模块的热替换
1,经过配置文件
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;
复制代码
2,经过命令行
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "NODE_ENV=development webpack-dev-server --config webpack.develop.config.js --hot",
},
复制代码
Tree-shaking能够用来剔除javascript中不用的死代码,它依赖静态的es6模块化语法,例如经过哦import 和export 导入导出,Tree-shaking最早在rollup中出现,webpack在2.0中将其引入,css中使用Tree-shaking须要引入Purify-CSS
浏览器在用户访问页面的时候,为了加快加载速度,会对用户访问的静态资源进行存储,可是每一次代码升级或是更新,都须要浏览器去下载新的代码,最方便和简单的更新方式就是引入新的文件名称。在webpack中能够在output纵输出的文件指定chunkhash,而且分离常常更新的代码和框架代码。经过NameModulesPlugin或是HashedModuleIdsPlugin使再次打包文件名不变。
要注意的第一点是,它对file-loader和url-loader支持很差,因此这两个loader就不须要换成happypack了,其余loader能够相似地换一下
babel-loader在执行的时候,可能会产生一些运行期间重复的公共文件,形成代码体积大冗余,同时也会减慢编译效率
能够加上cacheDirectory参数或使用 transform-runtime 插件试试
// webpack.config.js
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
}]
// .bablerc
{
"presets": [
"env",
"react"
],
"plugins": ["transform-runtime"]
}
复制代码
好比jQuery插件,react, react-dom等,代码量是不少的,打包起来可能会很耗时
能够直接用标签引入,而后在webpack配置里使用 expose-loader 或 externals 或 ProvidePlugin 提供给模块内部使用相应的变量
// @1
use: [{
loader: 'expose-loader',
options: '$'
}, {
loader: 'expose-loader',
options: 'jQuery'
}]
// @2
externals: {
jquery: 'jQuery'
},
// @3
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
复制代码
在webpack打包时,会有各类各样的路径要去查询搜索,咱们能够加上一些配置,让它搜索地更快好比说,方便改为绝对路径的模块路径就改一下,以纯模块名来引入的能够加上一些目录路径还能够善于用下resolve alias别名 这个字段来配置还有exclude等的配置,避免多余查找的文件,好比使用babel别忘了剔除不须要遍历的