在只要這幾步,webpack速成不是事兒一文中, 筆者簡單介紹了webpack的常見用法。能知足最基本的開發需求。在這篇文章中,再來談談一些較高級的應用。css
以前構建都是經過 npx webpack ...
這樣的方式執行構建命令。可能你會以爲這樣的方式不夠高效。甚至在某些特定的狀況下還須要設置 Node 的環境變量。根據環境變量值的不一樣,設置構建 --mode 的不一樣。html
scripts 配置的入口在 package.json
中,另外再介紹下。經過執行 npm i
默認安裝package.json中所有依賴。vue
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server"
},
複製代碼
cross-env 設置node環境變量的插件 npm i cross-env -Dnode
npm run dev
經過圖中能夠看到,npm run dev
至關於 npx webpack-dev-server
react
npm run build
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server",
"build": "cross-env NODE_ENV=production webpack"
},
複製代碼
先安裝插件cross-env
jquery
npm i cross-env -Dwebpack
執行 npm run dev
, 先設置環境變量 NODE_ENV=devlelopment, 而後執行 webpack 命令。web
爲何要設置環境變量呢? 設置環境變量後,能夠在打包構建時執行相應環境變量下的腳本。npm
process.env.NODE_ENV
拿到環境變量值。作你想作的事情。哈哈哈~
_DEV_
,相似於全局變量 window//應用: 在項目 src/index.js 文件中代碼裏區分開發或者是生產環境
if(__DEV__){
alert('開發環境')
}else{
alert('生產環境')
}
複製代碼
在webpack.config.js文件中,設置變量 let isDev = process.env.NODE_ENV === 'development',而後定義插件的disable屬性的值json
plugins: [
new ExtractTextWebpackPlugin({
filename: 'css/index.css',
disable: isDev
}),
],
複製代碼
.dll 爲後綴的文件稱爲動態連接庫,在一個動態連接庫中能夠包含給其餘模塊調用的函數和數據
react, react-dom 爲例
let path = require('path');
let webpack = require('webpack');
module.exports = {
entry: {
vendor: ['react', 'react-dom']
},
output: {
filename: '[name].js',
path: path.join(__dirname, 'dist'),
libraryTarget: "var", //構建後輸出js文件所屬規範, 若是 設置爲 commonjs, 則輸出文件符合 commonjs規範
library: '_dll_[name]', //構建後輸出js庫的名字
},
mode: 'development',
plugins: [
new webpack.DllPlugin({
name: '_dll_[name]',
path: path.join(__dirname, 'dist', '[name].manifest.json')
})
],
};
複製代碼
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server",
"react": "wepack --config webpack.config.react.js"
},
複製代碼
在webpack.config.js中配置插件
plugins: [
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'dist', 'vendor.manifest.json')
})
]
複製代碼
npm i babel-core babel-loader babel-preset-env babel-preset-react babel-preset-stage-0 -D
module: {
rules: [
{
test: /\.jsx?/,
use: 'babel-loader',
exclude:/node_modules/,
include:/src/
},
]
},
複製代碼
{
"presets": [
"env",
"stage-0",
"react"
]
}
複製代碼
npm run build
, 控制檯打印:[./node_modules/react-dom/index.js] delegated ./node_modules/react-dom/index.js from dll-reference _dll_vendor 42 bytes {index} [built]
[./node_modules/react/index.js] delegated ./node_modules/react/index.js from dll-reference _dll_vendor 42 bytes {index} [built]
複製代碼
由此能夠看出項目構建時是使用的預先構建好的react庫文件,從控制檯打印的構建耗時也明顯不一樣。
index.js
import './index.css';
// if(module.hot){
// console.log('熱更新');
// }
import React, { Component } from 'react'
import { render } from 'react-dom'
import a from './a.js'
render(<h1>hello zfpx</h1>, window.app)
複製代碼
x.js
import React, { Component } from 'react'
import { render } from 'react-dom'
import a from './a.js'
複製代碼
a.js
module.exports = {
a: 'a.js'
}
複製代碼
在webpack.config.js中配置:
optimization: {
splitChunks: {
cacheGroups: {
commons: { //提供公共組件, 只要超出0字節就生產新的包
chunks: 'initial',
//miniChunks: 2,
//maxInitalRequest: 5,
name: 'commons',
minSize: 0
},
vendor: {// 抽離第三插件
test: /node_modules/,
chunks: 'initial',
name: 'vender',
priority: 10,
enforce: true
}
}
}
},
複製代碼
執行構建腳本 npm run build
, 控制檯打印:
若是註釋相關構建信息:
在index.js中引入 jquery.js後,在a.js文件中想不引入jquery.js直接使用jquery對象
webpack.config.js中配置
module: {
rules: [
{
test: /jquery/,
use:[{
loader:'expose-loader',
options:'$'
}]
},
]
}
複製代碼
或者使用webpack提供的內置插件
// 提供全局變量插件
new webpack.ProvidePlugin({
$:'jquery'
}),
複製代碼
兩者的區別是神馬呢
1. $不會定義到window上
2. 只要是用到jquery(或者 $)的地方,當前bundle.js都會把jquery打包進去
複製代碼
webpack.config.js 相關配置爲:
entry: {
index: './src/index.js',
x: './src/x.js'
},
output: {
filename: '[name].[hash].bundle.js',
path: path.resolve(__dirname, 'dist'),
library: '_dll_[name]'
},
...
pugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',
hash: true
}),
]
複製代碼
index.js
console.log($)
複製代碼
x.js
console.log($);
複製代碼
從構建的日誌中能夠看出,index.js構建後的文件大小和x.js構建的文件大小一致
1.導入一次,就會暴露出來
2.$會定義到在window上
複製代碼
index.js
import $ from 'jquery'
console.log('index.js');
console.log($);
複製代碼
x.js
console.log('x.js');
console.log($);
console.log(window.$);
複製代碼
構建日誌:
瀏覽器打印日誌:
從構建的日誌中能夠看出,index.js構建後的文件大小和x.js構建的文件大小不一致 從瀏覽器打印日誌能夠看出,x.js在沒有直接import jquery時,也能夠拿到jquery對象
webpack還有不少其餘適用的功能,好比在使用vue時,經常會根據路由加載相應的組件js也就是咱們所說的 按需加載。能夠用到webpack代碼分離中的 動態導入和懶加載(dynamic imports),優化代碼加載,提高性能。