主要是看了阮一峰老师的wepack-demos做一下笔记,原链接:https://github.com/ruanyf/webpack-demos
什么是webpack?
webpack是为浏览器构建js模块脚本的前端工具
webpack需要一个配置文件,名叫:webpack.config.js
1 入口文件
webpack会读取入口文件,并构建成bundle.js文件
// centry file
module.exports={
entry:'./main.js',
output:{
filename:'bundle.js'
}
}
2 多入口文件
这对于多页面多应用很有用,因为每个页面都需要不同的js文件
// main1.js
document.write('Hello World
');
// main2.js
document.write('Hello Webpack
');
module.exports={
entry:{
bundle1:'./main1.js',
bundle2: './main2.js'
},
output:{
filename:'[name].js'
}
}
3 loaders
loaders是预处理器,在webpack构建之前会处理一些js文件,比如Babel-loader他可以处理jsx/es6的文件,转换成普通的浏览器可以识别js文件
// main.jsx
const React = require('react');
const ReactDOM = require('react-dom');
ReactDOM.render(
Hello, world!
,
document.querySelector('#wrapper')
);
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
modules:{
rules:[
{
test: /\.jsx?$/,
exclude: /node_modules/,
use:{
loader: 'babel-loader',
options:{
presets: ['es2015', 'react']
}
}
}
]
}
}
上面的代码使用babel-loader加载js文件,并需要babel的预处理插件babel-preset-es2015 babel-preset-react来处理es6和jsx文件
4 css-loader
预处理css文件
require('./app.css');
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
modules:{
rules:[
{
test: /\.css/,
use:['style-loader','css-loader']
}
]
}
}
5Image loader
加载图片的预处理器 url-loader
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
modules:{
rules:[
{
test: /\.(png|jpg)$/,
use: {
loader: 'url-loader',
options:{
limit: 8192
}
}
}
]
}
}
limit限制图片的大小8192字节
6 css Module
启用css的modules可以修改css的使用范围 通过:gloable
/* local scope 局部有效*/
.h1 {
color:red;
}
/* global scope 全局有效*/
:global(.h2) {
color: blue;
}
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
modules:{
rules:[
{
test: /\.css/,
use: [{
loader: 'style-loader',
},
{ loader: 'css-loader',
options: {
modules: true
}
}]
}
]
}
}
7 Uglifyjs plugins
js压缩插件
var webpack = require('webpack');
var UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
plugins:[
new UglifyJsPlugin()
]
}
8:HTML webpack plugin和open browser webpack plugin
HTML webpack plugin插件自动创建index.html文件,省去了你创建它的麻烦
open browser webpack plugin插件在webpack处理完js后会自动打卡浏览器访问网页。
var HtmlwebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
plugins:[
new HtmlwebpackPlugin({
title: 'Webpack-demo',
filename:'index.html'
}),
new OpenBrowserPlugin({
url: 'http://localhost:8080'
})
]
}
9: Environment flags 环境标志
main.js
document.write('Hello World
');
if (__DEV__) {
document.write(new Date());
}
webpack.config.js
var webpack = require('webpack')
var devFlagPlugin = new webpack.DefinePlugin({
_DEV_:JSON.stringify((JSON.parse(process.env.DEBUG||'false')))
})
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
plugins:[
devFlagPlugin,
]
}
// package.json
{
// ...
"scripts": {
"dev": "npx cross-env DEBUG=true webpack-dev-server --open",
},
// ...
}
10: code splitting 分割代码
对于大的web应用,把所有的js文件放在一个文件里是效率很低的,webpack允许把js文件分成几个分支
如果一些js文件只是在某些环境下才用到,可以使用命令加载他们
require.ensure(['./a.js'],function (require) {
var content = require('./a')
document.open();
document.write(`${content}
>`)
document.close()
})
require.ensure告诉webpack a.js文件要从bundle.js里分离出来,并单独成立一个js文件
11 使用bundle-loader分割代码
另一种分割代码的方法是使用bundle-loader
main.js
var load = require('bundle-loader!./a.js')
load(function (file) {
document.open()
document.write(`${file}
`)
document.close()
})
require('bundle-loader!./a.js')这句代码告诉webpack使用另一个分支加载a.js
12:Common chunk
当很多js文件有公共代码时,我们需要将这些公共当部分分割到一个文件下。这时
就需要使用CommonChunkPlugin
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
plugins:[
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: 'commons.js'
})
]
}
13: vendor chunk
你可以使用commonChunkPlugin将第三方插件从脚本提取到单独的文件中
main.js
var $ = require('jquery')
$('h1').text('hello world')
webpack.config.js
module.exports={
entry:{
app:'./main.js',
vendor:['jquery']
},
output:{
filename:'bundle.js'
},
plugins:[
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.js'
})
]
}
上面的代码entry.vendor:['jquery']告诉webpack jquery应该加载到公共模块vendor.js 中
如果你想不使用require引入,让$,jQuery作为全局变量在每个模块都可以用,可以使用providePlugin
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
plugins:[
new webpack.ProvidePlugin({
$:'jquery',
jQuery:'jquery'
})
]
}
14 Exposing global variables 公开全局变量
如果你想使用一些全局变量,但是不想把他们引入到bundle文件里,可以在webpack.config.js文件中启用
externals字段
data.js
var data = 'Hello world'
index.html
webpack只编译main.js为bundle.js 并不编译data.js
我们可以把data作为全局变量暴露出来
module.exports={
entry:'main.js',
output:{
filename:'bundle.js'
},
externals:{
'data':'data'
}
}
// main.jsx
var data = require('data');
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
{data}
,
document.body
);