本文是在請(qǐng)練完這16個(gè)webpack小例子基礎(chǔ)上補(bǔ)充的webpack2的版本
安裝
$ npm i -g webpack webpack-dev-server
配置
配置文件為 webpack.config.js
module.exports = {
entry: './main.js', // 入口文件
output: {
filename: 'bundle.js' //打包后的文件名
}
};
命令行
- webpack 構(gòu)建文件
- webpack -p 發(fā)布
- webpack --watch 監(jiān)聽項(xiàng)目
- webpack -d 包含source map方便調(diào)試
- webpack --colors讓打包界面更好看
在package.json中配置命令
{
// ...
"scripts": {
"dev": "webpack-dev-server --devtool eval --progress --colors",
"deploy": "NODE_ENV=production webpack -p"
},
// ...
}
使用
單文件入口
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
多文件入口
module.exports = {
entry: {
bundle1: './main1.js',
bundle2: './main2.js'
},
output: {
filename: '[name].js'
}
};
引用
<html>
<body>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html>
loaders
某些規(guī)律
在loaders的每個(gè)對(duì)象中,
- 使用多個(gè)loader,用!連接
- 傳遞參數(shù)是在loader名字后面加?驳癌,多個(gè)參數(shù)用&連接
babel-loader
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
]
}
};
module.loaders 區(qū)域是用來分配loader的. 像上面的代碼片段使用了 babel-loader 需要安裝插件 babel-preset-es2015 和 babel-preset-react to 編譯成 ES6 and React. 可以用query配置參數(shù)
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}
]
}
css-loader style-loader
先在css-loader中讀取css文件,這里為main.js
注意移動(dòng)在某個(gè)js文件中引入css文件
// main.js
require ('./xxx.css')
之后再style-loader中將樣式插入到html中
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{ test: /\.css$/, loader: 'style-loader!css-loader' },
]
}
};
image-loader
參數(shù)前是用次乓?連接的
依然和處理css格式的文件一樣,需要在main.js中require孽水,然后用fileloader
var img1 = document.createElement("img");
img1.src = require("./small.png");
document.body.appendChild(img1);
轉(zhuǎn)換為圖片文件
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]//url-loader 轉(zhuǎn)換圖片文件. 如果圖片的大小小于 8192 bytes,它將會(huì)轉(zhuǎn)成base64位的地址; 相反, 它就是普通地址.
}
};
Module
css module
CSS Module可以開啟全局變量和局部變量票腰,:global(...)表示全局變量,可以在全局中使用樣式
更多配置
:global(.h2) {
color: blue;
}
main.jsx
var React = require('react');
var ReactDOM = require('react-dom');
var style = require('./app.css');
ReactDOM.render(
<div>
<h1 className={style.h1}>Hello World</h1>
<h2 className="h2">Hello Webpack</h2>
</div>,
document.getElementById('example')
);
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader?modules'
}
]
}
};
使用composes
如需要引用以下兩個(gè)css文件:
style1.css
.text1{
......
color:yellow;
}
style2.css
.text2{...}
定義一個(gè)main.css供于繼承并引用
.context1{
composes:text1 from "path/style1.css";
color:red; // 這里會(huì)覆蓋原有樣式
}
.context2{
composes:text2 from "path/style2.css";
color:blue;
}
在main.js中
import styles from './main.css';
import React, { Component } from 'react';
export default class varA extends Component {
render() {
return (
<div className={styles.context1}>
<p className={styles.context2}>Style Variant A</p>
</div>
);
}
};
css動(dòng)畫的處理
anime.css
@keyframes bounce {
33% { transform: translateY(-20px); }
66% { transform: translateY(0px); }
}
.bounce {
animation: bounce 1s infinite ease-in-out;
}
main.css
.bounce{
composes: bounce from 'path/anime.css'
background-color:red;
}
main.js
import styles from './main.css';
import React, { Component } from 'react';
export default class varB extends Component {
render() {
return (
<div className={styles.bounce}>
</div>
);
}
}
Plugins
UglifyJs Plugin
可以優(yōu)化代碼女气,去掉本身附加的東西杏慰,減小js代碼量
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new uglifyJsPlugin({
compress: {
warnings: false
}
})
]
};
經(jīng)過打包后,main.js將會(huì)壓縮為
var o="Hello";o+=" World",document.write("<h1>"+o+"</h1>")
相關(guān)配置
html webpack plugin & open browser webpack plugin
html-webpack-plugin 創(chuàng)建 index.html,open-browser-webpack-plugin 打開瀏覽器
HtmlwebpackPlugin只支持node7
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-demos',
filename: 'index.html'
}),
new OpenBrowserPlugin({
url: 'http://localhost:8080'
})
]
};
環(huán)境變量
設(shè)置環(huán)境變量控制特定的代碼輸出路徑
var webpack = require('webpack');
module.exports = function() {
return {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG'])
]
};
};
// main.js
document.write('<h1>Hello World</h1>');
if (process.env.NODE_ENV === 'production') {
console.log('Welcome to production');
}
if (process.env.NODE_ENV === 'development') {
console.log('Welcome to development'); // show
}
if (process.env.DEBUG) {
console.log('Debugging output'); // show
}
注意:先命令行執(zhí)行 set NODE_ENV=development主卫,之后再wds
code splitting
a.js
module.export="i will be compiled to 0.bundle.js"
main.js
function determinated(){
// import()中不能寫入變量!!
import('./a').then((a)=>{
document.open()
document.write(`<h1>${a}</h1>`)
document.close()
}).catch((err)=>{
console.log(err)
})
}
determinated()
webpack.config.js不變逃默,但最后編譯出來的代碼被分成了兩個(gè)部分。
CommonsChunkPlugin
CommonsChunkPlugin是一個(gè)選擇性功能簇搅,可以創(chuàng)建一個(gè)單獨(dú)的文件(稱為一個(gè)塊)完域,由多個(gè)入口點(diǎn)之間共享的通用模塊組成。通過將公共模塊與捆綁分開瘩将,生成的分塊文件最初可以加載一次吟税,并存儲(chǔ)在高速緩存中供以后使用凹耙。這會(huì)使頁面優(yōu)化,因?yàn)闉g覽器可以快速提供來自緩存的共享代碼肠仪,而不是每當(dāng)訪問新頁面時(shí)被強(qiáng)制加載更大的包
// webpack.config.js
//CommonsChunkPlugins是webpack自身的方法肖抱,功能是提取兩個(gè)方法共有的代碼模塊
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
entry: {
bundle1: './main1.jsx',
bundle2: './main2.jsx'
},
output: {
filename: '[name].js'
},
module: {
loaders: [
{test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react'},
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "init'",
filename: "init.js",
}),
new uglifyJsPlugin({
compress: {
warnings: false
}
})
]
}
注意加載順序,要把通用模塊放在前面
<html>
<body>
<div id="a"></div>
<div id="b"></div>
<script src="init.js"></script>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html>
兩個(gè)bundle文件中都包含init
Vendor chunk
抽第三方庫异旧,并設(shè)置為變量意述,拿jquery舉例。比如:
// main.js
$('h1').text('Hello World');
$('h1').css('color','red');
// webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: {
app: './main.js',
vendor: ['jquery'],
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name:'vendor',
filename:'vendor.js'
}),
new webpack.ProvidePlugin({
$: 'jquery',//在這里設(shè)置一個(gè)變量
jQuery: 'jquery'
})
]
};
// 省略部分代碼
// 要先引入vendor.js
<script src="vendor.js"></script>
<script src="bundle.js"></script>
Exposing global variables
如果想引入某些模塊吮蛹,但不想被webpack預(yù)加載且依然可以通過CMD荤崇、AMD或者window/global全局的方式訪問。
比如潮针,想要全局引入data.js术荤,但不想被編譯到bundle中
// data.js
var data = 'Hello World';
// webpack.config.js
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{ test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' },
]
},
externals: {
'data2': 'data' //data2為注冊(cè)的全局變量
}
};
// main.js
var data2 = require('data2'); //直接require就可以了
var React = require('react');
var ReactDOM = require('react-dom');
var $ = require("jquery");
ReactDOM.render(
<h1>{data2}</h1>,
document.body
);
Hot Module Replacement
熱更新是在應(yīng)用程序運(yùn)行時(shí)不進(jìn)行頁面重新加載的情況下交換,添加或刪除模塊每篷。
親測(cè)webpack2只要wds就可以實(shí)現(xiàn)熱更新了瓣戚,以下配置適用于wepack1
兩種方法
- 命令行
$ webpack-dev-server --hot --inline
2.修改webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
'./index.js'
],
output: {
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['babel-loader?presets[]=es2015&presets[]=react'],
include: path.join(__dirname, '.')
}]
}
};