使用原因:
1.有一個很大的單頁應用,爲了提高開發效率,要將這個項目拆成多個模塊,開發完成後,這個項目可以正常跑了。但是因爲多個模塊是存在不同文件中的,因此加載這個單頁應用時,會發出多次請求。這時我們希望能夠把所有模塊打包成一個文件,這樣可以減少請求次數,提升體驗。
2.在開發這個單頁應用中,同樣是爲了提高開發效率,使用了一些js和css的擴展語言,如TypeScript及Less、stylus,這些擴展使我們可以更簡潔優雅地寫代碼,但是開發完成開始部署時,需要將它們進行相應的轉換,轉換成瀏覽器支持的語言。這時,我們希望能夠有個工具可以以很大的自動化程度去完成這個轉換工作。
3.在這個單頁應用開發完成後,我們爲了提高其性能,希望做一些列處理,比如把js進行壓縮。
簡單使用:
npm init 生成package.json文件
-
npm install webpack -g // 全局安裝
-
npm install webpack --save-dev // 只在當前項目裏安裝
寫webpack配置項文件
在項目根目錄創建名爲webpack.config.js的文件
var webpack = require('webpack');(引入)
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: {} ,
output: {} ,
module:{
loaders:[],
noParse:[]
},
plugins:[],
resolve:{}
devtool:'',
watch:boolean,
devServer:{}
}
module.exports = {
// 入口文件路徑,__dirname是根目錄
entry: __dirname + '/src/main.js', 要打包的文件
// 打包生成文件
output: {
path:__dirname + '/public'
, //通過HtmlWebpackPlugin插件生成的html文件存放在這個目錄下面
filename:'/js/[name].js'
, //編譯生成的js文件存放到根目錄下面的js目錄下面,如果js目錄不存在則自動創建
/*
* chunkFilename用來打包require.ensure方法中引入的模塊,如果該方法中沒有引入任何模塊則不會生成任何chunk塊文件
* 比如在main.js文件中,require.ensure([],function(require){alert(11);}),這樣不會打包塊文件
* 只有這樣纔會打包生成塊文件require.ensure([],function(require){alert(11);require('./greeter')})
* 或者這樣require.ensure(['./greeter'],function(require){alert(11);})
* chunk的hash值只有在require.ensure中引入的模塊發生變化,hash值纔會改變
* 注意:對於不是在ensure方法中引入的模塊,此屬性不會生效,只能用CommonsChunkPlugin插件來提取
* */
chunkFilename:'js/[chunkhash:8].chunk.js'
chunkname:個人理解chunkname就是未被列在entry中,但有些場景需要被打包出來的文件命名配置。比如按需加載(異步)模塊的時候,這樣的文件是沒有被列在entry中的使用CommonJS的方式異步加載模塊。
在require.ensure去加載模塊的時候纔會出現,chunkFileName,個人理解是cmd和amd異步加載,而且沒有給入口文件時,會生成了no-name的chunk,所以你看到的例子,chunkFileName一般都會是[id].[chunkhash].js,也就是這種chunk的命名一般都會是0.a5898fnub6.js
非入口文件的命名規則
},
plugins: [
new HtmlWebpackPlugin()
]
}
1、
css-loader & style-loader(loader只需要安裝)(針對css)
npm install --save-dev style-loader css-loader
module.exports = {
entry: __dirname + '/src/main.js',
output: {
path: __dirname + '/output',
filename: 'main.js'
},
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loaer!css-loader'
}
]
}
}
2、file-loader 和 url-loader(安裝url-loader即可)(針對img還有文件)
如果我們希望在頁面引入圖片(包括img的src和background的url)。當我們基於webpack進行開發時,引入圖片會遇到一些問題。
其中一個就是引用路徑的問題。拿background樣式用url引入背景圖來說,我們都知道,webpack最終會將各個模塊打包成一個文件,因此我們樣式中的url路徑是相對入口html頁面的,而不是相對於原始css文件所在的路徑的。這就會導致圖片引入失敗。這個問題是用file-loader解決的,file-loader可以解析項目中的url引入(不僅限於css),根據我們的配置,將圖片拷貝到相應的路徑,再根據我們的配置,修改打包後文件引用路徑,使之指向正確的文件。
另外,如果圖片較多,會發很多http請求,會降低頁面性能。這個問題可以通過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。相當於把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只需要引入這個文件就能訪問圖片了。當然,如果圖片較大,編碼會消耗性能。因此url-loader提供了一個limit參數,小於limit字節的文件會被轉爲DataURl,大於limit的還會使用file-loader進行copy。
url-loader和file-loader是什麼關係呢?簡答地說,url-loader封裝了file-loader。url-loader不依賴於file-loader,即使用url-loader時,只需要安裝url-loader即可,不需要安裝file-loader,因爲url-loader內置了file-loader。通過上面的介紹,我們可以看到,url-loader工作分兩種情況:1.文件大小小於limit參數,url-loader將會把文件轉爲DataURL;2.文件大小大於limit,url-loader會調用file-loader進行處理,參數也會直接傳給file-loader。因此我們只需要安裝url-loader即可。
例1:
{
test: /\.jpeg$/,
use: [
{
loader: 'url-loader',
options: {
limit: '1024'
}
},
]
}
例2:
{
test: /\.(woff|woff2|ttf|eot|svg)(\?t=[0-9]+)?$/,
loader: 'file-loader?name=./fonts/[name].[ext]'
放在output中指定的路徑下的fonts文件夾下,名字還是name,後綴是原本的test
}
, {
test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?|(woff|woff2|ttf|eot)$/,
loader: 'file-loader?name=./fonts/[name].[ext]'
}, {
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
query: {limit: 8192}
}
例3:
{
test: /\.jpeg$/,
// use: 'url-loader?limit=1024&name=[path][name].[ext]&publicPath=output/',
use: 'url-loader?limit=1024&name=[path][name].[ext]&outputPath=img/&publicPath=output/',
},
limit、name、outputPath、publicPath。其中limit已經說明過。file-loader相關的是name、outputPath和publicPath。下面解釋一下這3個參數
name表示輸出的文件名規則,如果不添加這個參數,輸出的就是默認值:文件哈希。加上[path]表示輸出文件的相對路徑與當前文件相對路徑相同,加上[name].[ext]則表示輸出文件的名字和擴展名與當前相同。加上[path]這個參數後,打包後文件中引用文件的路徑也會加上這個相對路徑。
outputPath表示輸出文件路徑前綴。圖片經過url-loader打包都會打包到指定的輸出文件夾下。但是我們可以指定圖片在輸出文件夾下的路徑。比如outputPath=img/,圖片被打包時,就會在輸出文件夾下新建(如果沒有)一個名爲img的文件夾,把圖片放到裏面。
publicPath表示打包文件中引用文件的路徑前綴,如果你的圖片存放在CDN上,那麼你上線時可以加上這個參數,值爲CDN地址,這樣就可以讓項目上線後的資源引用路徑指向CDN了。
3、autoprefixer-loader(loader只需安裝即可)(給css自動添加前綴)
寫css樣式時,有些情況下需要加樣式前綴以兼容不同的瀏覽器。手動添加css前綴會寫較多的重複代碼,降低開發效率。autoprefixer-loader爲我們提供了自動添加css前綴的功能。
npm install --save-dev autoprefixer-loader
{
test: /\.jpeg$/,
// use: 'url-loader?limit=1024&name=[path][name].[ext]&publicPath=output/',
use: 'url-loader?limit=1024&name=[path][name].[ext]&outputPath=img/&publicPath=output/',
},
4、less-loader(less)
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'autoprefixer-loader',
'less-loader'
]
},
5、extract-text-webpack-plugin(插件需要引入)(防止css在js中錯亂)
該插件的主要是爲了抽離css樣式,防止將樣式打包在js中引起頁面樣式加載錯亂的現象
npm install extract-text-webpack-plugin --save-dev
例1:
const ExtractTextPlugin = require("extract-text-webpack-plugin");(引入)
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("styles.css"),
]
}
use:指需要什麼樣的loader去編譯文件,這裏由於源文件是.css所以選擇css-loader
fallback:編譯後用什麼loader來提取css文件
publicfile:用來覆蓋項目路徑,生成該css文件的文件路徑
例2:
const ExtractTextPlugin = require("extract-text-webpack-plugin");(引入)
module: {
rules: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
]
},
plugins: [
new ExtractTextPlugin('css/[name].css')
],
例3:
module: {
rules: [
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'autoprefixer-loader',
'less-loader'
]
})
}
]
},
例4:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCss = new ExtractTextPlugin('[name]-one.css');
var extractLess = new ExtractTextPlugin('[name]-two.css');
plugins: [
extractCss,
extractLess
]
爲了讓打包後樣式生效,有兩種方法,一種是使用style-loader自動將css代碼放到生成的style標籤中插入到head標籤裏。另一種就是,使用extract-text-webpack-plugin插件,將樣式文件單獨打包,打包輸出的文件由配置文件中的output屬性指定。然後我們在入口HTML頁面寫個link標籤引入這個打包後的樣式文件。
插件和loader類似都是文件處理程序,但和loader不同,它不是針對特定類型文件的處理程序,而是在打包的整個過程這個更大的維度上起作用的處理程序。比如,js壓縮插件UglifyJsPlugin就是把打包後的js代碼進行壓縮。還有這篇文章要介紹的插件extract-text-webpack-plugin是把樣式文件單獨打包。
6、webpack-parallel-uglify-plugin(插件)(壓縮js)
npm i -D webpack-parallel-uglify-plugin
// 引入 ParallelUglifyPlugin 插件
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
module.exports = {
plugins: [
// 使用 ParallelUglifyPlugin 並行壓縮輸出JS代碼
new ParallelUglifyPlugin({
// 傳遞給 UglifyJS的參數如下:
uglifyJS: {
output: {
/*
是否輸出可讀性較強的代碼,即會保留空格和製表符,默認爲輸出,爲了達到更好的壓縮效果,
可以設置爲false
*/
beautify: false,
/*
是否保留代碼中的註釋,默認爲保留,爲了達到更好的壓縮效果,可以設置爲false
*/
comments: false
},
compress: {
/*
是否在UglifyJS刪除沒有用到的代碼時輸出警告信息,默認爲輸出,可以設置爲false關閉這些作用
不大的警告
*/
warnings: false,
/*
是否刪除代碼中所有的console語句,默認爲不刪除,開啓後,會刪除所有的console語句
*/
drop_console: true,
/*
是否內嵌雖然已經定義了,但是只用到一次的變量,比如將 var x = 1; y = x, 轉換成 y = 5, 默認爲不
轉換,爲了達到更好的壓縮效果,可以設置爲false
*/
collapse_vars: true,
/*
是否提取出現了多次但是沒有定義成變量去引用的靜態值,比如將 x = 'xxx'; y = 'xxx' 轉換成
var a = 'xxxx'; x = a; y = a; 默認爲不轉換,爲了達到更好的壓縮效果,可以設置爲false
*/
reduce_vars: true
}
}
}),
]
}
在通過 new ParallelUglifyPlugin() 實列化時,支持以下參數配置如下:
test: 使用正則去匹配哪些文件需要被 ParallelUglifyPlugin 壓縮,默認是 /.js$/.
include: 使用正則去包含被 ParallelUglifyPlugin 壓縮的文件,默認爲 [].
exclude: 使用正則去不包含被 ParallelUglifyPlugin 壓縮的文件,默認爲 [].
cacheDir: 緩存壓縮後的結果,下次遇到一樣的輸入時直接從緩存中獲取壓縮後的結果並返回,cacheDir 用於配置緩存存放的目錄路徑。默認不會緩存,想開啓緩存請設置一個目錄路徑。
workerCount:開啓幾個子進程去併發的執行壓縮。默認是當前運行電腦的 CPU 核數減去1。
sourceMap:是否爲壓縮後的代碼生成對應的Source Map, 默認不生成,開啓後耗時會大大增加,一般不會將壓縮後的代碼的
sourceMap發送給網站用戶的瀏覽器。
uglifyJS:用於壓縮 ES5 代碼時的配置,Object 類型,直接透傳給 UglifyJS 的參數。
uglifyES:用於壓縮 ES6 代碼時的配置,Object 類型,直接透傳給 UglifyES 的參數。
new ParallelUglifyPlugin({
uglifyJS: {},
test: /.js$/g,
include: [],
exclude: [],
cacheDir: '',
workerCount: '',
sourceMap: false
});
7、html-webpack-plugin(插件)(生成html)
npm i --save-dev html-webpack-plugin
例1:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
]
}
例2:
var htmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
entry: './src/script/main.js',
output: {
filename: 'js/bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: 'head'
})
]
}
inject有四個值: true
body
head
false
true
默認值,script標籤位於html文件的 body 底部body
script標籤位於html文件的 body 底部head
script標籤位於html文件的 head中false
不插入生成的js文件,這個幾乎不會用到的
favicon
給你生成的html文件生成一個 favicon
,值是一個路徑
plugins: [
new HtmlWebpackPlugin({
...
favicon: 'path/to/my_favicon.ico'
})
然後再生成的html中就有了一個 link
標籤
<link rel="shortcut icon" href="example.ico">
minify
使用minify會對生成的html文件進行壓縮。默認是false。html-webpack-plugin內部集成了 html-minifier
,因此,還可以對minify進行配置:(注意,雖然minify支持BooleanObject,但是不能直接這樣寫:minify: true , 這樣會報錯 ERROR in TypeError: Cannot use 'in' operator to search for 'html5' in true
, 使用時候必須給定一個 { }
對象 )
minify:{ removeComments: true,//刪除註釋 collapseWhiteSpace: true//刪除空格 }
...
plugins: [
new HtmlWebpackPlugin({
...
minify: {
removeAttributeQuotes: true // 移除屬性的引號
}
})
]
cache
默認是true的,表示內容變化的時候生成一個新的文件。
showErrors
當webpack報錯的時候,會把錯誤信息包裹再一個pre
中,默認是true。
chunks
chunks主要用於多入口文件,當你有多個入口文件,那就回編譯後生成多個打包後的文件,那麼chunks
就能選擇你要使用那些js文件
entry: {
index: path.resolve(__dirname, './src/index.js'),
devor: path.resolve(__dirname, './src/devor.js'),
main: path.resolve(__dirname, './src/main.js')
}
plugins: [
new httpWebpackPlugin({
chunks: ['index','main']
})
]
那麼編譯後:
<script type=text/javascript src="index.js"></script>
<script type=text/javascript src="main.js"></script>
- 如果你沒有設置chunks選項,那麼默認是全部顯示
excludeChunks
排除掉一些js
excludeChunks: ['devor.js']
// 等價於上面的
xhtml
一個布爾值,默認值是 false ,如果爲 true ,則以兼容 xhtml 的模式引用文件。
chunksSortMode
script的順序,默認四個選項: none
auto
dependency
{function}
'dependency' 不用說,按照不同文件的依賴關係來排序。
'auto' 默認值,插件的內置的排序方式,具體順序....
'none' 無序
{function} 提供一個函數
8、html-loader(html中的src)
在處理html上比較困難,不識別html中img標籤src引入的圖片。
html-webpack-plugin這種插件輔助處理html非常好,但卻仍然未解決html代碼中的圖片問題,未免美中不足
{
test: /\.html$/,
loader: "html?attrs=img:src img:data-src"
}
9.babel-loader(將es6轉化成es5)
babel-loader轉化ES6代碼
npm install babel-core babel-loader babel-preset-es2015 babel-plugin-transform-runtime --save-dev
{
test: /\.js$/,
exclude: /(node_modules|lib)/,
loader: 'babel-loader',
query: {
cacheDirectory: true,
presets: ['es2015'],
plugins: ['transform-runtime', 'transform-remove-strict-mode']
}
presets: ['es2015'] 所以安裝 babel-preset-es2015
'presets': [latest]所以安裝babel-preset-latest
plugins: ['transform-runtime', 'transform-remove-strict-mode']所以安裝 babel-plugin-transform-runtime和 babel-plugin-transform-remove-strict-mode 取消嚴格模式
babel 編譯時只轉換語法,幾乎可以編譯所有時新的 JavaScript 語法,但並不會轉化BOM裏面不兼容的API
比如 Promise,Set,Symbol,Array.from,async 等等的一些API
這時候就需要 polyfill 來轉轉化這些API
babel polyfill 有三種:
* babel-runtime
* babel-plugin-transform-runtime
* babel-polyfill
transform-runtime
在使用webpack打包時,需配置到babel中
"plugins": [
["transform-runtime", {
"helpers": false,
"polyfill": false,
"regenerator": true,
"moduleName": "babel-runtime"
}]
]
transform-runtime 會有幾個配置項,不表標註默認爲true
在webpack中,babel-plugin-transform-runtime 實際上是依賴babel-runtime
因爲babel編譯es6到es5的過程中,babel-plugin-transform-runtime這個插件會自動polyfill es5不支持的特性,
這些polyfill包就是在babel-runtime這個包裏
core-js 、regenerator等 poiiyfill
babel-runtime和 babel-plugin-transform-runtime的區別是,相當一前者是手動擋而後者是自動擋,每當要轉譯一個api時都要手動加上require('babel-runtime'),
而babel-plugin-transform-runtime會由工具自動添加,主要的功能是爲api提供沙箱的墊片方案,不會污染全局的api,因此適合用在第三方的開發產品中。
runtime轉換器插件主要做了三件事:
* 當你使用generators/async方法、函數時自動調用babel-runtime/regenerator
* 當你使用ES6 的Map或者內置的東西時自動調用babel-runtime/core-js
* 移除內聯babel helpers並替換使用babel-runtime/helpers來替換
transform-runtime優點
* 不會污染全局變量
* 多次使用只會打包一次
* 依賴統一按需引入,無重複引入,無多餘引入
transform-runtime缺點
* 不支持實例化的方法Array.includes(x) 就不能轉化
* 如果使用的API用的次數不是很多,那麼transform-runtime 引入polyfill的包會比不是transform-runtime 時大
總的來說一句話,你可以使用內置的一些東西例如Promise,Set,Symbol等,就像使用無縫的使用polyfill,來使用babel 特性,並且無全局污染、極高代碼庫適用性。
雖然這種方法的優點是不會污染全局,但是,實例的方法,
Array.prototype.includes();
babel-polyfill
babel-polyfill則是通過改寫全局prototype的方式實現,比較適合單獨運行的項目。
開啓babel-polyfill的方式,可以直接在代碼中require,或者在webpack的entry中添加,也可以在babel的env中設置useBuildins爲true來開啓。
但是babel-polyfill會有近100K,
打包後代碼冗餘量比較大,
對於現代的瀏覽器,有些不需要polyfill,造成流量浪費
污染了全局對象
https://www.jianshu.com/p/7bc7b0fadfc2
這個加載器(loaders)還支持以下加載器特定選項:
-
cacheDirectory
:默認值false
。當設置時,給定的目錄將用於緩存加載器的結果。未來的webpack構建將嘗試從緩存中讀取,以避免在每次運行時,需要運行 Babel 重新編譯過程可能帶來的高昂的開銷。 如果值爲空(loader: 'babel-loader?cacheDirectory'
)或true
(loader: babel-loader?cacheDirectory=true
),加載器將使用node_modules/.cache/babel-loader
中的默認緩存目錄,或者如果在任何根目錄中找不到node_modules
文件夾,加載器將使用默認的操作系統臨時文件目錄。 -
cacheIdentifier
:默認是由 babel-core 的版本組成的字符串,babel-loader 的版本,.babelrc文件的內容(如果存在)和環境變量BABEL_ENV
的值,並返回到NODE_ENV
環境變量。可以將其設置爲自定義值,以在標識符更改時強制緩存無效。 -
babelrc
:默認true
。當爲false
時,將忽略.babelrc
文件(除了extends
選項引用的那些文件)。 -
forceEnv
:默認將解析BABEL_ENV
,然後NODE_ENV
。允許您在加載器級別覆BABEL_ENV/NODE_ENV
。對於同構應用程序,在爲客戶端和服務器配置不同的babel時有用。
注意: sourceMap
選項被忽略,相反,當webpack配置爲使用sourceMaps時,會自動啓用它們(通過devtool
配置選項)。
10、loader
中!
代表的含義(從右到左)
{ test : /\.css\.less$/, loader : 'style!css!less' }
就代表了先使用less加載器來解釋less文件,然後使用css加載器來解析less解析後的文件,依次類推
11、module.noParse(不被loaders解析的模塊)
使用了noParse
的模塊將不會被loaders
解析,所以當我們使用的庫如果太大,並且其中不包含require
、define
或者類似的關鍵字的時候(因爲這些模塊加載並不會被解析,所以就會報錯),我們就可以使用這項配置來提升性能。
例如下面的例子:在basic/
目錄中新增no-parse.js
var cheerio = require('cheerio');
module.exports = function() {
console.log(cheerio);
}
webpack.config.js
中新增如下配置:
module : {
loaders : [
{ test : /\.js$/, loader : 'babel' },
{ test : /\.css$/, loader : 'style!css' }
],
noParse : /no-parse.js/
}
當執行打包後,在瀏覽器中打開index.html
時,就會報錯require is not defined
noParse: [/moment-with-locales/]
module.noParse是webpack的另一個很有用的配置項,如果你 確定一個模塊中沒有其它新的依賴就可以配置這項,webpack將不再掃描這個文件中的依賴。
12、vendors(第三方包)
項目中用到了一些第三方庫,如vue、vue-router、jquery、boostrap等。這些庫我們基本上是不會改動源代碼的,並且項目初期就基本確定了,不會再添加。所以把它們打包在一起。當然這個也是要考慮大小不超過500KB的,如果是用到了像ueditor這樣的大型工具庫,還是要單獨打包的。
配置文件的寫法是很簡單的,在entry中配一個名爲vendor的就好,比如:
entry: {
vendor: ['vue', 'vue-router', './public/vendor/jquery/jquery']
},
爲了把第三方庫拆分出來(用<script>標籤單獨加載),我們還需要用webpack的CommonsChunkPlugin插件來把它提取一下,這樣他就不會與業務代碼打包到一起了。代碼:
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor');
]
- vendor的意思是依賴的第三方庫,不會經常變更的,如你代碼裏的jQuery這種
- CommonsChunkPlugin是指被你重複引用的chunks。可能是vendor,也可能是你自己的某個公共組件
13、CommonsChunkPlugin
當你的 webpack 構建任務中有多個入口文件,而這些文件都 require 了相同的模塊,如果你不做任何事情,webpack 會爲每個入口文件引入一份相同的模塊,顯然這樣做,會使得相同模塊變化時,所有引入的 entry 都需要一次 rebuild,造成了性能的浪費,CommonsChunkPlugin 可以將相同的模塊提取出來單獨打包,進而減小 rebuild 時的性能消耗。
同時將多個入口文件相同的js打包處一個共同的後,也可以利用緩存,使加載第二頁面的時候不需要再加載共同文件。
commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common', 'common.[hash].js');
CommonsChunkPlugin是內置在webpack裏的,直接這樣用即可:
const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin
14、webpack的ProvidePlugin配置
原本是:
import $ from 'jquery';
纔可以使用$
如果用providePlugin進行配置
- ProvidePlugin,是webpack的內置模塊
- 以jquery爲例,用ProvidePlugin進行實例初始化後,jquery就會被自動加載並導入對應的node模塊中
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
_: 'lodash'
}),
15、process.env.NODE_ENV(環境變量)
"build-win": "SET NODE_ENV=production && webpack --config build/webpack.config.js"
16、resolve.alias
爲模塊設置別名,能夠讓開發者指定一些模塊的引用路徑。對一些經常要被import或者require的庫,如react,我們最好可以直接指定它們的位置,這樣webpack可以省下不少搜索硬盤的時間。
resolve: {
extensions: [‘.js‘, ‘.vue‘],
alias: {
‘@‘: path.resolve(__dirname, ‘src‘),
‘@scss‘: path.resolve(__dirname, ‘src‘, ‘scss‘),
}
}
// 原本這樣寫
import hongAlert from ‘./../src/scss/icon.scss‘
// 現在可以這樣寫
import hongAlert from ‘@scss/icon.scss‘
17、resolve.root和resolve.modulesDirectories
root是通過絕對路徑的方式來定義查找模塊的文件夾。可以是一個數組,主要是用來增加模塊的搜尋位置使用的。
這裏root的值必須是絕對路徑,使用path.resolve設置。
var path = require('path');
// ...
resolve: {
root: [
path.resolve('./app/modules'),
path.resolve('./vendor/modules')
]
}
這樣設置後,會增加搜索app/modules和vendor/modules下所有node_modules裏面的模塊。
modulesDirectories是用來設置搜索的目錄名的,默認值:["web_modules", "node_modules"]。如果把值設置成["mydir"]
, webpack會查詢 “./mydir”, “../mydir”, “../../mydir”等。
注意: Passing"../someDir","app","."or an absolute path isn’t necessary here. Just use a directory name, not a path. Use only if you expect to have a hierarchy within these folders. Otherwise you may want to use theresolve.root
option instead.
18、HotModuleReplacement(模塊熱替換)(插件)
new webpack.HotModuleReplacementPlugin() 不需要引入
改動了js,會自動編譯刷新頁面,能夠方便開發。這是inline
參數的作用
假如一個項目很龐大,打包編譯需要很長時間,那麼通過HMR,就可以只替換必要的模塊(修改過的模塊),從而大大減少開發中等待編譯的時間
19、devtool(調試工具)
開發總是離不開調試,方便的調試能極大的提高開發效率,不過有時候通過打包後的文件,你是不容易找到出錯了的地方,對應的你寫的代碼的位置的,Source Maps
就是來幫我們解決這個問題的。
通過簡單的配置,webpack
就可以在打包時爲我們生成的source maps
,這爲我們提供了一種對應編譯文件和源文件的方法,使得編譯後的代碼可讀性更高,也更容易調試。
source-map:在一個單獨的文件中產生一個完整且功能完全的文件。這個文件具有最好的source map
,但是它會減慢打包速度;
cheap-module-source-map:在一個單獨的文件中生成一個不帶列映射的map
,不帶列映射提高了打包速度,但是也使得瀏覽器開發者工具只能對應到具體的行,不能對應到具體的列(符號),會對調試造成不便;
eval-source-map:使用eval
打包源文件模塊,在同一個文件中生成乾淨的完整的source map
。這個選項可以在不影響構建速度的前提下生成完整的sourcemap
,但是對打包後輸出的JS文件的執行具有性能和安全的隱患。在開發階段這是一個非常好的選項,在生產階段則一定不要啓用這個選項;
cheap-module-eval-source-map:這是在打包文件時最快的生成source map
的方法,生成的Source Map
會和打包後的JavaScript
文件同行顯示,沒有列映射,和eval-source-map
選項具有相似的缺點;
正如上表所述,上述選項由上到下打包速度越來越快,不過同時也具有越來越多的負面作用,較快的打包速度的後果就是對打包後的文件的的執行有一定影響。
對小到中型的項目中,eval-source-map
是一個很好的選項,再次強調你只應該開發階段使用它
cheap-module-eval-source-map
方法構建速度更快,但是不利於調試,推薦在大型項目考慮時間成本時使用。
20、devServer:配置開發服務功能
npm install webpack-dev-server --save-dev
npm install webpack-cli -D
/*設置基本目錄結構,也就是你想要使用服務的目錄地址*/
contentBase:path.resolve(__dirname,'dist'),
/*服務器的IP地址,可以使用IP也可以使用localhost*/
host:'localhost',
/*服務端壓縮是否開啓,目前開不開都行,想關你就關*/
compress:true,
/*配置服務端口號,建議別用80,很容易被佔用,你要是非要用也是可以的。*/
port:9090
21、less-loader
還有下載less
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
'less-loader'
]
}
]
}