閱讀目錄
webpack簡(jiǎn)述
按照webapck官網(wǎng)所說,webpack是一個(gè)模塊打包工具(webpack is a module bundler)。它接收依賴的模塊,將其轉(zhuǎn)化為靜態(tài)資源。
webpack與眾不同的三大核心概念
Code Spliting
Loaders
Plugin System
配置(configuration)
CLI
如果使用CLI,webpack將會(huì)讀取webpack.config.js文件(或者通過--config選項(xiàng)傳遞的文件),這個(gè)文件需要暴露這樣的配置對(duì)象:
module.exports = { // configuration};
常見CLI option
1)開發(fā)環(huán)境簡(jiǎn)寫 -d
等價(jià)于:--debug --devtool source-map --output-pathinfo
2)生產(chǎn)環(huán)境簡(jiǎn)寫 -p
等價(jià)于:--optimize-minimize --optimize-occurrence-order
3)監(jiān)視模式 --watch
4)配置文件 --config example.config.js
指定新的配置文件,而不是默認(rèn)的webpack.config.js
5)常見的顯示選項(xiàng)
--progress
--display-chunks
--display-reasons
--display-error-details
--display-modules
--display-exclude
可以通過script來定義腳本,然后npm run 命令名。
一個(gè)簡(jiǎn)單的配置對(duì)象,注意不是json,只是簡(jiǎn)單的object
{ context: __dirname + "/app", entry: "./entry", output: { path: __dirname + "/dist", filename: "bundle.js" } }
context
context:根目錄(絕對(duì)路徑!)。可以認(rèn)為是文件查找的上下文。默認(rèn)process.cwd()
entry
entry:包的入口點(diǎn),有三種形式
一個(gè)string
一個(gè)由多個(gè)string構(gòu)成的array
一個(gè)object(多頁(yè)面場(chǎng)景下),key是chunk的name,value可以是string或者array
output
output.filename
不要在這里指定絕對(duì)路徑
多入口情況下使用占位符
[name] 模塊名稱
[hash] 模塊編譯后的(整體)Hash值
[chunkhash] 分片的Hash值,可以認(rèn)為是文件的版本號(hào),也可以認(rèn)為是文件的MD5值,在靜態(tài)資源的版本管理中非常有用
output.path
output.publicPath
指定 public URL地址,當(dāng)我們要將output的文件放在不同的域名或者CDN上時(shí)十分有用
module
module.loaders 一個(gè)自動(dòng)應(yīng)用的loaders的數(shù)組,每項(xiàng)(item)可以有這些屬性:
test: A condition that must be met
exclude: A condition that must not be met
include: An array of paths or files where the imported files will be transformed by the loader
loader: A string of “!” separated loaders
loaders: An array of loaders as string
resolve
resolve.alias
模塊別名定義,方便后續(xù)直接引用別名
resolve: { alias: { AppStore : 'js/stores/AppStores.js',//之后直接 require('AppStore') } }
resolve.root
包含你模塊的目錄(絕對(duì)路徑),也可以是一個(gè)目錄數(shù)組,這個(gè)設(shè)置應(yīng)該被用于添加個(gè)人目錄到webpack查找路徑里
必須是個(gè)絕對(duì)路徑,不要這樣寫./app/modules
resolve.modulesDirectories
這是一個(gè)目錄數(shù)組,用來解析到當(dāng)前目錄以及祖先目錄和查找模塊。這個(gè)函數(shù)的工作原理和node如何查找node_modules目錄很像。比如如果值為["mydir"],webpack會(huì)查找“./mydir”, “../mydir”, “../../mydir”等等
默認(rèn): ["web_modules", "node_modules"]
resolve.extensions
一個(gè)用來解析模塊的拓展名數(shù)組。比如,為了發(fā)現(xiàn)一個(gè)CoffeeScript文件,你的數(shù)組里應(yīng)該包含字符串".coffee"
默認(rèn): ["", ".webpack.js", ".web.js", ".js"]
注意:設(shè)置這個(gè)選項(xiàng)將會(huì)重寫默認(rèn)值
externals
指定不該被webpack打包的模塊,但是在打包后的包中仍然保留了請(qǐng)求。
我們可以通過它來暴露全局變量,而在需要的文件中直接require或import就可以了
externals: { jquery: 'jQuery'}
plugins
給編譯器添加額外的插件
各種loaders
webpack 可以使用 loader 來預(yù)處理文件。這允許你打包除 JavaScript 之外的任何靜態(tài)資源。你可以使用 Node.js 來很簡(jiǎn)單地編寫自己的 loader。
loader的使用有三種方法,分別是:
在require中顯式指定,即上面看到的用法
在配置項(xiàng)(webpack.config.js)中指定
在命令行中指定
轉(zhuǎn)換ES6語(yǔ)法或React語(yǔ)法
通過presets選擇ES6特性,也可以在package.json中指定
解決babel-loader處理React的preset問題:npm i --save-dev babel-preset-react
2)css相關(guān)
style-loader 將模塊的導(dǎo)出作為樣式添加到DOM中
css-loader 解析CSS文件后,使用import加載,并且返回CSS代碼,可以在loader后面?modules以支持CSS Module
less-loader 加載和轉(zhuǎn)譯LESS文件
sass-loader 加載和轉(zhuǎn)譯SASS/SCSS文件,須先安裝node-sass,windows可能安裝出錯(cuò),使用cnpm i node-sass --save-dev或者如下:
npm install --save-dev node-sass --registry=https://registry.npm.taobao.org --disturl=https://npm.taobao.org/dist --sass-binary-site=http://npm.taobao.org/mirrors/node-sass
postcss-loader 使用PostCSS加載和轉(zhuǎn)譯CSS/SSS文件,可以進(jìn)行autoprefixer
CSS中@import另一個(gè)CSS怎么處理?(非SASS、LESS)
給css-loader添加參數(shù)
loader: 'style-loader!css-loader?importLoaders=1!postcss-loader'
3)模板相關(guān)
html-loader 導(dǎo)出HTML為字符串,需要引用靜態(tài)資源
jade-loader 加載Jade模板并返回一個(gè)函數(shù)
markdown-loader 將Markdown轉(zhuǎn)譯為HTML
handlebars-loader 將Handlebars轉(zhuǎn)換為HTML
ejs-loader 將underscore模板轉(zhuǎn)換為HTML
4)圖片相關(guān)
file-loader
url-loader 與file-loader,但如果文件小于限制,可以返回 data URL
image-loader 壓縮圖片
components模板引用相對(duì)路徑圖片不會(huì)替換?
可以使用絕對(duì)路徑或者這樣寫src="${require('../../assets/bg.png')}"
5)bundle-loader
bundle-loader是一個(gè)用來在運(yùn)行時(shí)異步加載模塊的loader。可以用來做代碼分割
6)exports-loader
可以從模塊中導(dǎo)出變量。
在實(shí)際使用中,用exports-loader最多的場(chǎng)景是將某些不支持模塊化規(guī)范的模塊所聲明的全局變量作為模塊內(nèi)容導(dǎo)出。
如下可以導(dǎo)出全局變量Hello,exports-loader還可以支持同時(shí)導(dǎo)出多個(gè)變量,例如exports?HELLO,WORLD
module.exports = { module:{ loaders:[ { test: require.resolve('./hello'), loader: "exports?Hello" } ] } };
7)imports-loaders
用于向一個(gè)模塊的作用域內(nèi)注入變量(Can be used to inject variables into the scope of a module)
8)expose-loader
把一個(gè)模塊導(dǎo)出并付給一個(gè)全局變量
require("expose?libraryName!./file.js");// Exposes the exports for file.js to the global context on property "libraryName".// In web browsers, window.libraryName is then available.
各種plugins
參數(shù):
template html模板地址,默認(rèn)為webpack.config.js所在的目錄
inject 插入位置
title
date等
2)CommonsChunkPlugin
將多個(gè)入口起點(diǎn)之間共享的公共模塊,生成為一些 chunk,并且分離到單獨(dú)的 bundle 中,例如,1vendor.bundle.js 和 app.bundle.js
3)ExtractTextWebpackPlugin
從 bundle 中提取文本(CSS)到分離的文件(app.bundle.css)
4)ProvidePlugin
ProvidePlugin可以將模塊作為一個(gè)變量,被webpack在其他每個(gè)模塊中引用。只有你需要使用此變量的時(shí)候,這個(gè)模塊才會(huì)被 require進(jìn)來。多數(shù)之前遺留的模塊,會(huì)依賴于已存在的某些特定全局變量,比如jQuery插件中的$或者jQuery。在這種場(chǎng)景,你可以在每次遇到全局標(biāo)識(shí)符$的時(shí)候,在webpack中預(yù)先設(shè)置var $ = require(“jquery”)。
module.exports = { plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }) ] };
Environment flags
windows下使用cross-env的npm包兼容處理,可以在package.json設(shè)置如下:
"scripts": { "clear": "rm -rf build&& mkdir build", "start": "npm run clear&& cross-env NODE_ENV=development webpack-dev-server --host 0.0.0.0 --devtool eval --progress --color --profile", "deploy": "npm run clear&& cross-env NODE_ENV=production webpack -p --progress"}
webpack.config.js
var isProduction = process.env.NODE_ENV === 'production'; plugins: [new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') } })]
Code splitting(代碼分割)
使用require.ensure
// main.jsrequire.ensure(['./a'], function(require) { var content = require('./a'); document.open(); document.write('<h1>' + content + '</h1>'); document.close(); });// a.jsmodule.exports = 'Hello World';
require.ensure告訴Webpack,./a.js應(yīng)該從bundle.js分離并且打包成一個(gè)單獨(dú)的文件
注意require.ensure只會(huì)加載模塊而不會(huì)去解析
也可以用bundle-loader進(jìn)行代碼分割
// main.js// Now a.js is requested, it will be bundled into another filevar load = require('bundle-loader!./a.js');// To wait until a.js is available (and get the exports)// you need to async wait for it.load(function(file) { document.open(); document.write('<h1>' + file + '</h1>'); document.close(); });
vendor chunk
可以用CommonsChunkPlugin插件將公共庫(kù)(vendor)打包成一個(gè)單獨(dú)的文件
var webpack = require('webpack');module.exports = { entry: { app: './main.js', vendor: ['jquery'], }, output: { filename: 'bundle.js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin(/* chunkName= */'vendor', /* filename= */'vendor.js') ] };
模塊熱替換(Hot Module Replacement)
npm i webpack-dev-server --save-dev
主要參考資料
標(biāo)簽: webpack
http://www.cnblogs.com/ang-/p/6599348.html