webpack v4 從dev到prd的方法
概述
本月迎來(lái)了 v4 正式版的發(fā)布,本文用于學(xué)習(xí)新特性和總結(jié)開發(fā)必用plugin & loader,從dev到prd,走你~
Big changes
Environment
Node.js 4 is no longer supported. Source Code was upgraded to a higher ecmascript version.
Usage
You have to choose (mode or --mode) between two modes now: production or development
本次新版本中引入了 mode 配置項(xiàng),開發(fā)者可在 none,development(開發(fā) ) 以及 production(產(chǎn)品)三種模式間選擇。該配置項(xiàng)缺省情況下默認(rèn)使用 production 模式。
- development 模式給你極致的開發(fā)體驗(yàn),包含瀏覽器調(diào)試相關(guān)工具,極快的增量編譯,豐富全面的報(bào)錯(cuò)信息...
- production 模式則包含大量發(fā)版優(yōu)化,代碼壓縮,絲般潤(rùn)滑的運(yùn)行時(shí)優(yōu)化,開發(fā)相關(guān)代碼的排除,易用,etc.
- none 不使用預(yù)設(shè),等于老版本中全部自己配置的原始狀態(tài)。
eg:
webpack --mode development
Usage
- Some Plugin options are now validated
- CLI has been move to webpack-cli, you need to install webpack-cli to use the CLI
- The ProgressPlugin (--progress) now displays plugin names
- At least for plugins migrated to the new plugin system
新版中將 webpack 命令行工具拆分到單獨(dú)的倉(cāng)庫(kù)中,所以需要額外安裝 webpack-cli。
npm init -y //初始化項(xiàng)目 npm install webpack webpack-cli -D //安裝webpack webpack-cli 依賴 npx webpack --mode development // npx可以直接運(yùn)行node_modules/.bin目錄下面的命令
或者通過(guò)配置package.json的script build
"scripts": {
"build": "webpack --mode development",
},
加載loader方法總結(jié)
use
module: {
rules:[
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
}
css-loader用來(lái)解析處理CSS文件中的url路徑,要把CSS文件變成一個(gè)模塊
多個(gè)loader是有順序要求的,從右往左寫,因?yàn)檗D(zhuǎn)換的時(shí)候是從右往左轉(zhuǎn)換
此插件先用css-loader處理一下css文件,再用style-loader把CSS文件變成style標(biāo)簽插入head中
loader
module: {
rules:[
{
test: /\.css$/,
loader: ["style-loader", "css-loader"]
},
]
}
use+loader
module: {
rules:[
{
test: /\.css$/,
use:[
{ loader:"style-loader"},
{
loader: 'css-loader',
options: {sourceMap: true}
}
]
}
]
}
這三種loader的寫法,最后打包的結(jié)果相同
loader中的options配置項(xiàng)可以用"?"跟在加載器后面
eg:
{
test: /\.jpeg$/,
use: 'url-loader?limit=1024&name=[path][name].[ext]&outputPath=img/&publicPath=output/',
}
為以下配置的簡(jiǎn)寫
{
test: /\.jpeg$/,
use: {
loader:'url-loader',
options:{
limit:1024,
name:[path][name].[ext],
outputPath:img/
publicPath:output/'
}
}
}
開發(fā)必備的loader&plugins
- css-loader
- babel-loader
講ES6代碼轉(zhuǎn)換為ES5
{
test: /\.js/,
use: {
loader: 'babel-loader',
query: {
presets: ["env", "stage-0", "react"]
}
}
},
babel-loader的預(yù)設(shè)可以添加在query中,也可以在項(xiàng)目根目錄添加 .babelrc 文件
.babelrc
{
"presets": [
"env",
"stage-0",
"react"
]
}
html-webpack-plugin
插件的基本作用就是生成html文件。原理很簡(jiǎn)單:
將 webpack中entry配置的相關(guān)入口thunk 和 extract-text-webpack-plugin抽取的css樣式 插入到該插件提供的template或者templateContent配置項(xiàng)指定的內(nèi)容基礎(chǔ)上生成一個(gè)html文件,具體插入方式是將樣式link插入到head元素中,script插入到head或者body中。
const HtmlWebpackPlugin = require('html-webpack-plugin');
new HtmlWebpackPlugin({
template: './src/index.html',//指定產(chǎn)的HTML模板
filename: `index.html`,//產(chǎn)出的HTML文件名
title: 'index',
hash: true,// 會(huì)在引入的js里加入查詢字符串避免緩存,
minify: {
removeAttributeQuotes: true
}
}),
可以用 cnpm search html-webpack-plugin 查找想用loader的用法
less-loader sass-loader
優(yōu)化向prd進(jìn)發(fā)
提取公共的css代碼
它會(huì)將所有的入口 chunk(entry chunks)中引用的 *.css,移動(dòng)到獨(dú)立分離的 CSS 文件。因此,你的樣式將不再內(nèi)嵌到 JS bundle 中,而是會(huì)放到一個(gè)單獨(dú)的 CSS 文件(即 styles.css)當(dāng)中。 如果你的樣式文件大小較大,這會(huì)做更快提前加載,因?yàn)?CSS bundle 會(huì)跟 JS bundle 并行加載。
npm i extract-text-webpack-plugin@next -D
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
let cssExtract = new ExtractTextWebpackPlugin({
filename: 'css/css.css',
allChunks: true
});
module:{
rules:[
{
test: /\.css$/,//轉(zhuǎn)換文件的匹配正則
loader: cssExtract.extract({
use: ["css-loader?minimize"]
})
},
]
}
plugins:[
...... ,
+ cssExtract
]
盡量減少文件解析,用resolve配置文件解析路徑,include
rules: {
test: /\.js$/,
loader:'babel-loader',
include: path.resolve(__dirname, 'src'),//只轉(zhuǎn)換或者編譯src 目錄 下的文件
exclude: /node_modules/ //不要解析node_modules
}
resolve.mainFields
WebpackTest | | | - src | | - index.js | | - lib | | - fetch | | | browser.js | node.js | package.json | | - webpack.config.js
當(dāng)從 npm 包中導(dǎo)入模塊時(shí)(例如,引入lib下的庫(kù)),此選項(xiàng)將決定在 package.json 中使用哪個(gè)字段導(dǎo)入模塊。根據(jù) webpack 配置中指定的 target 不同,默認(rèn)值也會(huì)有所不同。
package.json
lib文件夾下的package.json中配置相對(duì)應(yīng)模塊的key
{
"name": "fetch",
"version": "1.0.0",
"description": "",
"node": "./node.js",
"browser": "./browser.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
webpack.config.js
在resolve解析對(duì)象中,加入lib的路徑
resolve: {
extensions: ['.js', '.json'],
mainFields: ['main', 'browser', 'node'],
modules: [path.resolve('node_modules'), path.resolve('lib')]
}
index.js
這樣在index.js中引用第三方庫(kù)時(shí),會(huì)去查找modules下的路徑中是否配置了所需的文件,知道在package.json中找到mainFields中的key對(duì)應(yīng)文件,停止。
let fetch = require('fetch');
console.log(fetch);
打包后 console.log出的對(duì)象

如果交換mainFields中的key順序
mainFields: ['main', 'node','browser']
打包后 console.log出的對(duì)象,因?yàn)檎业搅薻ey=node對(duì)應(yīng)的文件就停止了查找

DllReferencePlugin
這個(gè)插件是在 webpack 主配置文件中設(shè)置的, 這個(gè)插件把只有 dll 的 bundle(們)(dll-only-bundle(s)) 引用到需要的預(yù)編譯的依賴。
新建webpack.react.config.js
const path = require('path');
const webpack = require('webpack')
module.exports = {
entry: {
react: ['react', 'react-dom']
},
output: {
path: path.join(__dirname, 'dist'),// 輸出動(dòng)態(tài)連接庫(kù)的文件名稱
filename: '[name]_dll.js',
library: '_dll_[name]'//全局變量的名字,其它會(huì)從此變量上獲取到里面的模塊
},
// manifest 表示一個(gè)描述文件
plugins: [
new webpack.DllPlugin({
name: '_dll_[name]',
path: path.join(__dirname, 'dist', 'manifest.json')//最后打包出來(lái)的文件目錄和名字
})
]
}
在entry入口寫入要打包成dll的文件,這里把體積較大的react和react-dom打包
output中的關(guān)鍵是library的全局變量名,下文詳細(xì)說(shuō)明dll&manifest工作原理
打包dll文件
webpack --config webpack.react.config.js --mode development
打包出來(lái)的manifest.json節(jié)選

打包出來(lái)的react_dll.js節(jié)選

可見(jiàn)manifest.json中的 name值就是
output:{
library:_dll_react
}
manifest.json就是借書證,_dll_react就像圖書館書籍的條形碼,為我們最終找到filename為react_dll.js的參考書
使用“參考書”
在webpack.config.js中加入“借書證”
new webpack.DllReferencePlugin({
manifest: path.join(__dirname, 'dist', 'manifest.json')
})
再運(yùn)行
webpack --mode development
打包速度顯著變快

打包后的main.js中,react,react-dom.js也打包進(jìn)來(lái)了,成功~
import React from 'react';\n//import ReactDOM from 'react-dom';
(function(module, exports, __webpack_require__) {
"use strict";
eval("\n\n//import name from './base';\n//import React from 'react';\n//import ReactDOM from 'react-dom';\n//import ajax from 'ajax';\n//let result = ajax('/ajax');\n\n//ReactDOM.render(<h1>{result}</h1>, document.getElementById('root'));\n// fetch fetch.js fetch.json fetch文件夾\n//let fetch = require('fetch');\n//console.log(fetch);\n//let get = require('../dist/bundle.js');\n//get.getName();\nconsole.log('hello');\n\nvar name = 'zfpx';\nconsole.log(name);\nif (true) {\n var s = 'ssssssssssssssssssssssss';\n console.log(s);\n console.log(s);\n console.log(s);\n console.log(s);\n}\n\n//# sourceURL=webpack:///./src/index.js?");
/***/ })
/******/ });
未完待續(xù)
- webpack.ProvidePlugin
- 拷貝靜態(tài)資源
- 壓縮css(npm i -D purifycss-webpack purify-css)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js實(shí)現(xiàn)網(wǎng)站最上邊可關(guān)閉的浮動(dòng)廣告條代碼
這篇文章主要介紹了js實(shí)現(xiàn)網(wǎng)站最上邊可關(guān)閉的浮動(dòng)廣告條代碼,涉及javascript基于鼠標(biāo)事件操作頁(yè)面元素樣式的實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-09-09
JavaScript登錄驗(yàn)證碼的實(shí)現(xiàn)
驗(yàn)證碼功能真的無(wú)處不在,為了提高網(wǎng)站的安全性,驗(yàn)證碼功能是必要的環(huán)節(jié),今天小編通過(guò)本文給大家分享js登錄驗(yàn)證碼的實(shí)現(xiàn),感興趣的朋友跟著小編一起學(xué)習(xí)吧2016-10-10
簡(jiǎn)單實(shí)用的網(wǎng)頁(yè)表格特效
簡(jiǎn)單實(shí)用的網(wǎng)頁(yè)表格特效...2006-07-07
父元素與子iframe相互獲取變量和元素對(duì)象的具體實(shí)現(xiàn)
父元素與子iframe相互獲取變量和元素對(duì)象的方法有很多,本文提供了一些不錯(cuò)的示例另收集網(wǎng)上的一些,可以參考下2013-10-10
Bootstrap實(shí)現(xiàn)漸變頂部固定自適應(yīng)導(dǎo)航欄
這篇文章給大家介紹了Bootstrap實(shí)現(xiàn)漸變頂部固定自適應(yīng)導(dǎo)航欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
JS實(shí)現(xiàn)定時(shí)自動(dòng)消失的彈出窗口
這篇文章介紹了JS實(shí)現(xiàn)定時(shí)自動(dòng)消失的彈出窗口,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
詳解JavaScript中關(guān)于this指向的4種情況
這篇文章主要介紹了JavaScript中關(guān)于this指向的4種情況,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04

