本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。css
原生浏览器,不能很好的识别 ES6 以及更高版本中ES moudule
模块引入方式。代码中使用ES moudule
,能够经过webpack进行打包编译成浏览器识别的语法。html
// 全局安装
npm install webpack -g
// 全局下打包
webpack index.js
复制代码
// 本地项目安装
npm install webpack --save-dev
// 本地项目打包
npx webapck index.js //直接执行 npx webpack 会调用默认配置文件 webpck.config.js
复制代码
// scripts标签使用
"scripts": {
"build": "webpack"
},
// 本地项目打包
npm run build
复制代码
webpack处理js文件之外的文件时,就须要借助loader了node
webpack 可使用 loader 来预处理文件。这容许你打包除 JavaScript 以外的任何静态资源。webpack
将文件发送到输出文件夹,并返回(相对)URL。 可打包:图片、text等各类文件es6
像 file loader 同样工做,但若是文件小于限制,能够返回 data URL 若是小于limit
值,直接以base64形式打包到js中,大于和file-loader同样,生成文件。配合使用,优化。web
将模块的导出做为样式添加到 DOM 中npm
解析 CSS 文件后,使用 import 加载,而且返回 CSS 代码
浏览器
// importLoaders 用于配置「css-loader 做用于 @import 的资源以前」有多少个 loader。
模块化打包css文件
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2, // 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
},
},
'postcss-loader',
'sass-loader',
],
复制代码
// modules 选项启用/禁用css模块规范和设置基本行为。
options: {
modules: true,
},
复制代码
使用 PostCSS 加载和转译 CSS/SSS 文件sass
webpack 有着丰富的插件接口(rich plugin interface)。webpack 自身的多数功能都使用这个插件接口。这个插件接口使 webpack 变得极其灵活。bash
clean-webpack-plugin
A webpack plugin to remove/clean your build folder(s).
HtmlWebpackPlugin
简单建立 HTML 文件,用于服务器访问
SplitChunksPlugin
此配置对象表示splitchunksplugin的默认行为。
// webpack.config.js
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'async', // 包括:all、async、initial(同步)
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
automaticNameMaxLength: 30,
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
};
复制代码
MiniCssExtractPlugin
这个插件将css提取到单独的文件中。它为每一个包含css的js文件建立一个css文件。它支持按需加载css和sourcemap。
它创建在新的webpack v4特性(模块类型)之上,须要webpack 4才能工做。
与extract-text-webpack-plugin
相比:
TODO:
此选项控制是否生成,以及如何生成 source map。
// 最佳实践:
development: cheap-module-eval-source-map
production: cheap-module-eval-source-map
复制代码
webpack-dev-server 为你提供了一个简单的 web server,而且具备 live reloading(实时从新加载) 功能。
注意
:new HtmlWebpackPlugin( { // Also generate a test.html filename: 'index.html', // 使用webapck-dev-server打包至内存,须要index.html template: './index.html' } ),
模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它容许在运行时更新全部类型的模块,而无需彻底刷新。
babel-loader @babel/core
处理:@babel/preset-env
tree shaking 是一个术语,一般用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export。这个术语和概念其实是由 ES2015 模块打包工具 rollup 普及起来的。
代码分离是 webpack 中最引人注目的特性之一。此特性可以把代码分离到不一样的 bundle 中,而后能够按需加载或并行加载这些文件。代码分离能够用于获取更小的 bundle,以及控制资源加载优先级,若是使用合理,会极大影响加载时间。
经常使用的代码分离方法有三种
entry
配置手动地分离代码。SplitChunksPlugin
去重和分离 chunk
。Code splitting这个概念一直都有,并不是webpack首创,只是如今webpack将此功能集成了。 注意: webapck在作代码分割时,打包同步和异步引入的代码是有区别的。
webpack
才会将相似lodash
的库文件和业务代码作分割打包,不然会打包到一个文件中。// 同步引入
import _ from 'lodash'
_.join(['a', 'b'], '$$')
// webpack.config.js
optimization: {
splitChunks: {
chunks: "all"
}
},
复制代码
webpack
也会默认将库文件和业务代码分开打包。// 异步引入
function getComponent() {
return import('lodash').then(({default: _}) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a', 'b'], '$$$')
return element
})
}
getComponent().then(element => {
document.body.appendChild(element)
})
复制代码
Prefetching/Preloading
webpack v4.6.0+ 添加了预取和预加载的支持。
在声明 import 时,使用下面这些内置指令,可让 webpack 输出 "resource hint(资源提示)",来告知浏览器:
与 prefetch 指令相比,preload 指令有许多不一样之处:
懒加载或者按需加载,是一种很好的优化网页或应用的方式。这种方式其实是先把你的代码在一些逻辑断点处分离开,而后在一些代码块中完成某些操做后,当即引用或即将引用另一些新的代码块。这样加快了应用的初始加载速度,减轻了它的整体体积,由于某些代码块可能永远不会被加载。
Caching
?既然contenthash变了,为何浏览器访问,仍是不是最新的?Output Filenames
复制代码
咱们能够经过替换output.filename
中的 substitutions
设置,来定义输出文件的名称。webpack 提供了一种使用称为 substitution(可替换模板字符串)
的方式,经过带括号字符串来模板化文件名。其中,[contenthash] substitution
将根据资源内容建立出惟一 hash
。当资源内容发生变化时,[contenthash]
也会发生变化。
Shimming
webpack
compiler 可以识别遵循 ES2015
模块语法、CommonJS
或 AMD
规范编写的模块。然而,一些 third party(第三方库)
可能会引用一些全局依赖(例如 jQuery
中的 $
)。所以这些 library
也可能会建立一些须要导出的全局变量。这些 "broken modules(不符合规范的模块)
" 就是 shim(预置依赖)
发挥做用的地方。
Environment Variables
想要消除 开发环境 和 生产环境 之间的 webpack.config.js
差别,你可能须要环境变量(environment variable)
。
webpack
命令行 环境配置 的 --env
参数,能够容许你传入任意数量的环境变量。而在 webpack.config.js
中能够访问到这些环境变量。例如--env.production
或 --env.NODE_ENV=local
(NODE_ENV
一般约定用于定义环境类型,查看这里)。
webpack --env.NODE_ENV=local --env.production --progress
复制代码