webpack4.0方才宣布,官网自称4.0最大的特性就是零设置。本文就细致引见一下webpack4.0实战那些事儿。
1 什么是WebPack
打包机
WebPack能够看作是模块打包机:它做的事变是,剖析你的项目构造,找到JavaScript模块以及别的的一些浏览器不能直接运转的拓展言语(Scss,TypeScript等),并将其打包为适宜的花样以供浏览器运用。
构建
构建就是把源代码转换成宣布到线上的可实行 JavaScrip、CSS、HTML 代码,包含以下内容。
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。
- 文件优化:紧缩 JavaScript、CSS、HTML 代码,紧缩兼并图片等。
- 代码支解:提取多个页面的大众代码、提取首屏不须要实行部份的代码让其异步加载。
- 模块兼并:在采纳模块化的项目里会有很多个模块和文件,须要构建功能把模块分类兼并成一个文件。
- 自动革新:监听当地源代码的变化,自动从新构建、革新浏览器。
- 代码校验:在代码被提交到堆栈前须要校验代码是不是相符范例,以及单元测试是不是经由过程。
- 自动宣布:更新完代码后,自动构建出线上宣布代码并传输给宣布体系。
构建实际上是工程化、自动化头脑在前端开辟中的表现,把一系列流程用代码去完成,让代码自动化地实行这一系列庞杂的流程。 构建给前端开辟注入了更大的生机,解放了我们的临盆力。
2 疾速设置
1 中心观点
- Entry:进口,Webpack 实行构建的第一步将从 Entry 最先,可笼统成输入。
- Module:模块,在 Webpack 里统统皆模块,一个模块对应着一个文件。Webpack 会从设置的 Entry 最先递归找出一切依靠的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码兼并与支解。
- Loader:模块转换器,用于把模块原内容依据需求转换成新内容。
- Plugin:扩大插件,在 Webpack 构建流程中的特定机遇注入扩大逻辑来转变构建效果或做你想要的事变。
- Output:输出效果,在 Webpack 经由一系列处置惩罚并得出终究想要的代码后输出效果。
2 webpack的事情流程
- 1 Webpack 启动后会从Entry里设置的Module最先递归剖析 Entry 依靠的一切 Module。
- 2 每找到一个 Module, 就会依据设置的Loader去找出对应的转换划定规矩,对 Module 举行转换后,再剖析出当前 Module 依靠的 Module。
- 3 这些模块会以 Entry 为单元举行分组,一个 Entry 和其一切依靠的 Module 被分到一个组也就是一个 Chunk。
- 4 末了 Webpack 会把一切 Chunk 转换成文件输出。 在全部流程中 Webpack 会在适当的机遇实行 Plugin 里定义的逻辑。
3 设置webpack
1) 初始化npm
npm init -y
在要举行打包的目次下初始化npm, 在控制台实行以上敕令后会天生一个package.json
的文件。
2) install
npm install webpack webpack-cli -D
由于从4.0最先,webpack拆离开两个包离别是webpack
和webpack-cli
3) 设置文件webpack.config.js
module.exports = {
entry:设置进口文件的地点
output:设置出口文件的地点
module:设置模块,重要用来设置差别文件的加载器
plugins:设置插件
devServer:设置开辟效劳器
}
接下来我们就逐一引见一下它们的设置。
3 设置开辟效劳器
1 install
npm install webpack-dev-server -D
2 设置参数
devServer:{
contentBase:path.resolve(__dirname,'dist'),// 设置开辟效劳运转时的文件根目次
host:'localhost',// 开辟效劳器监听的主机地点
compress:true, // 开辟效劳器是不是启动gzip等紧缩
port:8080 // 开辟效劳器监听的端口
}
3 设置启动参数
"scripts": {
"dev": "webpack-dev-server --open --mode development "
}
note
从4.0最先,运转webpack时肯定要加参数 --mode development
或许--mode production
,离别对应开辟环境和临盆环境。
4 设置module
1 什么是loader
module
重要用来设置差别文件的加载器。谈到加载就离不开loader
,那什么是loader
呢?
loader的观点
经由过程运用差别的Loader,Webpack能够要把差别的文件都转成JS文件,比方CSS、ES6/7、JSX等。
-
test
:婚配处置惩罚文件的扩大名的正则表达式 -
use
:loader称号,就是你要运用模块的称号 -
include/exclude
:手动指定必需处置惩罚的文件夹或屏障不须要处置惩罚的文件夹 -
query
:为loaders供应分外的设置选项
loader
的三种写法
- use
- loader
- use+loader
2 支撑加载css文件
install
npm install style-loader css-loader -D
设置加载器
module: {
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader'],
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}
]
}
note
注重:加载器的加载递次为从右至左。即先用css-loader
剖析然后用style-loader
将剖析后的css
文件增加到Head
标签中。
3 支撑图片
install
npm install file-loader url-loader html-withimg-loader -D
-
file-loader
处理CSS等文件中的引入图片途径题目 -
url-loader
当图片较小的时刻会把图片BASE64编码,大于limit参数的时刻照样运用file-loader 举行拷贝
设置加载器
{
test: /\.(png|jpg|gif|svg|bmp|eot|woff|woff2|ttf)$/,
loader: {
loader: 'url-loader',
options: {
limit: 5 * 1024,// 图片大小 > limit 运用file-loader, 反之运用url-loader
outputPath: 'images/'// 指定打包后的图片位置
}
}
}
usage – 手动增加图片
let logo = require('./images/logo.png');
let img = new Image();
img.src = logo;
document.body.appendChild(img);
usage – 在CSS中引入图片
.img-bg{
background: url(./images/logo.png);
width:173px;
height:66px;
}
usage – 在HTML中运用图片
{
test:/\.(html|html)$/,
use:'html-withimg-loader',
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}
4 编译less 和 sass
1) install
npm install less less-loader node-sass sass-loader -D
2) 设置加载器
把编译好的代码放到head内里
{
test: /\.css$/,
loader: ['style-loader', 'css-loader']
}, {
test: /\.less$/,
loader: ['style-loader', 'css-loader']
}, {
test: /\.scss$/,
loader: ['style-loader', 'css-loader']
}
把编译好的代码放到零丁的文件内里
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
let cssExtract = new ExtractTextWebpackPlugin('css.css');
let lessExtract = new ExtractTextWebpackPlugin('less.css');
let sassExtract = new ExtractTextWebpackPlugin('sass.css');
...
{
test: /\.css$/,
loader: cssExtract.extract({
use: ['css-loader?minimize']
})
}, {
test: /\.less$/,
loader: lessExtract.extract({
use: ['css-loader?minimize', 'less-loader']
})
}, {
test: /\.scss$/,
loader: sassExtract.extract({
use: ['css-loader?minimize', 'sass-loader']
})
}
5 处置惩罚CSS3属性前缀
为了浏览器的兼容性,偶然刻我们必需到场-webkit,-ms,-o,-moz这些前缀
- Trident内核:重要代表为IE浏览器, 前缀为-ms
- Gecko内核:重要代表为Firefox, 前缀为-moz
- Presto内核:重要代表为Opera, 前缀为-o
- Webkit内核:产要代表为Chrome和Safari, 前缀为-webkit
install
npm install postcss-loader autoprefixer -D
usage
postcss-loader
须要设置 postcss.config.js
文件,postcss.config.js 内容以下:
module.exports = {
plugins: [
require('autoprefixer')
]
}
// 把 post-laoder push 到css的loader数组中
{
test: /\.css$/,
loader: ['style-loader', 'css-loader', 'postcss-loader']
}, {
test: /\.less$/,
loader: ['style-loader', 'css-loader', 'less-loader']
}, {
test: /\.scss$/,
loader: ['style-loader', 'css-loader', 'sass-loader']
}
6 转义ES6/ES7/JSX
Babel实际上是一个编译JavaScript的平台,能够把ES6/ES7,React的JSX转义为ES5。
install
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react -D
设置加载器
{
test:/\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ["env","stage-0","react"]// env --> es6, stage-0 --> es7, react --> react
}
},
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}
5 设置plugins
设置插件
1 自动产出html
我们愿望自动能产出HTML文件,并在内里引入产出后的资本。
install
npm install html-webpack-plugin -D
usage
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // 指定产出的模板
filename: 'base.html', // 产出的文件名
chunks: ['common', 'base'], // 在产出的HTML文件里引入哪些代码块
hash: true, // 称号是不是哈希值
title: 'base', // 能够给模板设置变量名,在html模板中挪用 htmlWebpackPlugin.options.title 能够运用
minify: { // 对html文件举行紧缩
removeAttributeQuotes: true // 移除双引号
}
})
]
2 星散CSS
由于CSS的下载和JS能够并行,当一个HTML文件很大的时刻,我们能够把CSS零丁提取出来加载
install
npm install extract-text-webpack-plugin@next -D
usage
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
let cssExtract = new ExtractTextWebpackPlugin('css.css');
let lessExtract = new ExtractTextWebpackPlugin('less.css');
let sassExtract = new ExtractTextWebpackPlugin('sass.css');
...
module: {
rules: [
{
test: /\.css$/,
loader: cssExtract.extract({
use: ['css-loader?minimize']
})
}, {
test: /\.less$/,
loader: lessExtract.extract({
use: ['css-loader?minimize', 'less-loader']
})
}, {
test: /\.scss$/,
loader: sassExtract.extract({
use: ['css-loader?minimize', 'sass-loader']
})
}
]
}
...
plugins: [
cssExtract,
lessExtract,
sassExtract
]
处置惩罚图片途径题目
const PUBLIC_PATH='/';
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath:PUBLIC_PATH
}
3 拷贝静态文件
偶然项目中没有援用的文件也须要打包到目的目次
install
npm install copy-webpack-plugin -D
usage
const CopyWebpackPlugin = require('copy-webpack-plugin');
plugins: [
new CopyWebpackPlugin([{
from: path.join(__dirname, 'public'), // 从那里复制
to: path.join(__dirname, 'dist', 'public') // 复制到那里
}])
]
4 打包前先清空输出目次
install
npm install clean-webpack-plugin -D
usage
const CleanWebpackPlugin = require('clean-webpack-plugin');
plugins: [
new CleanWebpackPlugin([path.join(__dirname, 'dist')])
]
5 紧缩JS
install
npm install uglifyjs-webpack-plugin -D
usage
onst UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
plugins: [
new UglifyjsWebpackPlugin()
]
6 怎样调试打包后的代码
webapck经由过程设置能够自动给我们source maps文件,map文件是一种对应编译文件和源文件的要领
usage
devtool:'eval-source-map'
devtool的参数详解
-
source-map
把映照文件天生到零丁的文件,最完全最慢 -
cheap-module-source-map
在一个零丁的文件中发作一个不带列映照的Map -
eval-source-map
运用eval打包源文件模块,在同一个文件中天生完全sourcemap -
cheap-module-eval-source-map
sourcemap和打包后的JS偕行显现,没有映照列
7 打包第三方类库
1 直接引入
import _ from 'lodash';
alert(_.join(['a','b','c'],'@'));
2 插件引入
new webpack.ProvidePlugin({
_:'lodash'
})
8 watch
当代码发作修改后能够自动从新编译
watch: true,
watchOptions: {
ignored: /node_modules/, //疏忽不必监听变动的目次
aggregateTimeout: 500, // 文件发作转变后多长时间后再从新编译(Add a delay before rebuilding once the first file changed )
poll:1000 //每秒讯问的文件变动的次数
}
9 效劳器代办
假如你有零丁的后端开辟效劳器 API,而且愿望在同域名下发送 API 要求 ,那末代办某些 URL 会很有效。
//要求到 /api/users 如今会被代办到要求 http://localhost:9000/api/users。
proxy: {
"/api": "http://localhost:9000",
}
10 resolve剖析
1 extensions
指定extension以后能够不必在require或是import的时刻加文件扩大名,会顺次尝试增加扩大名举行婚配
resolve: {
//自动补全后缀,注重第一个必需是空字符串,后缀肯定以点开首
extensions: ["",".js",".css",".json"],
},
2 alias
设置别号能够加速webpack查找模块的速率
- 每当引入jquery模块的时刻,它会直接引入jqueryPath,而不须要从node_modules文件夹中按模块的查找划定规矩查找
- 不须要webpack去剖析jquery.js文件
const bootstrap = path.join(__dirname,'node_modules/bootstrap/dist/css/bootstrap.css');
resolve: {
alias: {
'bootstrap': bootstrap
}
}
11 暴露全局对象
install
npm install expose-loader -D
action
把模块的导出暴露给全局变量,
usage-1
require("expose-loader?libraryName!./file.js");
usage-2
rules: [{
test: require.resolve('jquery'),// 注重 这里是require的resolve 要领
use: {
loader: "expose-loader",
options: "$"
}
}]
13 多进口
偶然刻我们的页面能够不止一个HTML页面,会有多个页面,所以就须要多进口
usage
// 多个进口,能够给每一个进口增加html模板
entry: {
index: './src/index.js',
main:'./src/main.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[hash].js',
publicPath:PUBLIC_PATH
},
plugins: [
new HtmlWebpackPlugin({
minify: {
removeAttributeQuotes:true
},
hash: true,
template: './src/index.html',
chunks:['index'],
filename:'index.html'
}),
new HtmlWebpackPlugin({
minify: {
removeAttributeQuotes:true
},
hash: true,
chunks:['login'],
template: './src/login.html',
filename:'login.html'
})]
]
14 externals
假如我们想援用一个库,然则又不想让webpack打包,而且又不影响我们在顺序中以CMD、AMD或许window/global全局等体式格局举行运用,那就能够经由过程设置externals。
webpack.config.js
externals: {
jquery: "jQuery"
//假如要在浏览器中运转,那末不必增加什么前缀,默认设置就是global
},
index.js
const $ = require("jquery");
const $ = window.jQuery;