上文介紹了webpack入門,本文將詳細介紹webpack實用配置javascript
以entry.js打包爲bundle.js爲例,出口的filename能夠設置爲[id]、[name]、[hash]、[chunkhash]等替換形式,以下所示css
var webpack = require('webpack'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: '[id]-[name]-[hash].js'//出口名稱 } }
則出口文件爲0-main-0c1dce21f6c5db455fb4.jshtml
若是index.html要引用打包後的js文件,因爲文件名稱不肯定,並很差解決。這時,就須要使用html-webpack-plugin插件。該插件並非內置插件,因此須要安裝java
npm install html-webpack-plugin
HtmlWebpackPlugin簡化了HTML文件的建立,以便爲webpack包提供服務。這對於在文件名中包含每次會隨着變異會發生變化的哈希的webpack bundle尤爲有用node
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: '[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ title: 'match',//生成的html文件的標題爲'match' filename: 'index.html'//生成的html文件名稱爲'index.html' }) ] }
經過以上的配置,若是在當前路徑,index.html不存在,則生成;若是存在,則替換jquery
[注意]若是htmlwebpackplugin不進行配置,參數爲空, plugins: [new HtmlWebpackPlugin()]。默認地,生成的html文件名稱爲'index.html',標題爲'Webpack APP' webpack
【標籤位置】web
htmlwebpackplugin插件的經常使用設置是設置script標籤插入的位置,默認插入到body標籤中,但可使用inject:'head',設置插入到head標籤中正則表達式
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ inject:'head',//將script標籤插入到head標籤中 filename: 'index-[hash].html',//生成的html文件名稱爲'index.html' }) ] }
【圖標設置】npm
設置favicon屬性,能夠設置網頁的小圖標
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ favicon:'./icon.ico' }) ] }
【壓縮】
設置minify屬性,能夠壓縮html文件,默認爲false,即不壓縮
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ minify:{ removeComments: true,//刪除註釋 collapseWhitespace:true//刪除空格 } }) ] }
使用webpack打包後的index.html代碼以下
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Webpack App</title></head><body><script type="text/javascript" src="js/0-main-8128c0c26a4449da7a05.js"></script></body></html>
HtmlWebpackPlugin除了提供模塊版本號的功能,還可使用模板文件
例如,模板文件爲template.html,內容以下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>template</title> </head> <body> <script src="test.js"></script> <div>test</div> </body> </html>
webpack配置文件以下
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ filename: 'index-[hash].html',//生成的html文件名稱爲'index.html' template:'template/template.html'//模板文件爲'template.html' }) ] }
生成的index-[hash].html以'template.html'文件爲模板
[注意]若是在htmlwebpackplugin中使用了模板,則指定title不會生效,由於要以模板的title爲準
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ title:'test', filename: 'index-[hash].html',//生成的html文件名稱爲'index.html' template:'template/template.html'//模板文件爲'template.html' }) ] }
【傳參】
模塊文件固然是能夠傳參的,通常地,使用ejs語法。例如,在模板文件中,使用<%= htmlWebpackPlugin.options.title %>,便可讀取htmlWebpackPlugin插件中'title'屬性的值
[注意]模板文件中的'htmlWebpackPlugin'是固定的,不能隨意更改。與webpack.config.js文件中,require()該插件的命名無關
//webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ title:'test', template:'template/template.html',//模板文件爲'template.html' dateData: new Date() }) ] } //template.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <div><%=htmlWebpackPlugin.options.dateData %></div> </body> </html>
【模板組件】
下面利用模板組件組合成一個html文件,以ejs模板語言爲例
//webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ template:'template/template.html'}) ] } //template.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div> <% include template/header.html %> </div> <ul> <% var arr = [1,2,3,4,5] %> <% for(var i = 0; i < arr.length; i++){ %> <li><%=arr[i] %></li> <% } %> </ul> <div> <% include template/footer.html %> </div> </body> </html> //header.html <div>我是頭部</div> //footer.html <div>我是尾部</div>
運行結果報錯,提示子模板加載失敗
這是由於HtmlWebpackPlugin插件並不具有ejs模板語言全部的功能,其中一個就是不能識別<%include %>語句,這時須要安裝一個ejs-compiled-loader
npm install ejs-compiled-loader
安裝完成後,修改配置文件以下,表示使用ejs-compiled-loader來編譯template.html
[注意]該插件中的include路徑相對於webpack配置文件的位置,而不是模板文件template.html的位置
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ template:'ejs-compiled-loader!template/template.html'}) ] }
結果以下
對於多頁面來講,通常地,有多個入口文件。不一樣的html頁面輸出對應不一樣的入口文件。 插件plugins()是一個數組,每new一個HtmlWebpackPlugin(),就能夠輸出一個html頁面。這裏有兩個重要的屬性:chunks和excludeChunks,chunks表示所包含的入口文件,excludeChunks表示要排除的入口文件
//webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { a:'./src/js/a.js', b:'./src/js/b.js', c:'./src/js/c.js' }, output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ filename:'a.html', template:'src/template/template.html', title:'this is a', chunks:['a'] }), new HtmlWebpackPlugin({ filename:'b.html', template:'src/template/template.html', title:'this is b', chunks:['b'] }), new HtmlWebpackPlugin({ filename:'c.html', template:'src/template/template.html', title:'this is c', excludeChunks:['a','b'] }), ] }
結果以下
//a.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>this is a</title> </head> <body> <div></div> <script type="text/javascript" src="js/2-a-9828ea84bd8c12c19b5f.js"></script></body> </html> //b.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>this is b</title> </head> <body> <div></div> <script type="text/javascript" src="js/1-b-9828ea84bd8c12c19b5f.js"></script></body> </html> //c.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>this is c</title> </head> <body> <div></div> <script type="text/javascript" src="js/0-c-9828ea84bd8c12c19b5f.js"></script></body> </html>
在前面的例子中,都是以連接的形式引入入口文件的。有時,爲了追求性能,會將其處理爲內聯的形式。這裏就須要安裝一個擴展插件html-webpack-inline-source-plugin,專門用來處理入口文件內聯的
$ npm install --save-dev html-webpack-inline-source-plugin
該插件的使用很簡單,使用require()語句引入後,在插件plugins()新建一個html-webpack-inline-source-plugin對象,而後在html-webpack-plugin對象中添加inlineSource屬性便可
inlineSource: '.(js|css)$' // embed all javascript and css inline
//webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin'); module.exports = { entry: './entry.js', output:{ path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, plugins: [ new HtmlWebpackPlugin({ inlineSource: '.(js|css)$' }), new HtmlWebpackInlineSourcePlugin() ] }
結果以下
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Webpack App</title> </head> <body> <script type="text/javascript">/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { document.write('It works.') /***/ }) /******/ ]);</script></body> </html>
下面使用babel來進行es最新標準的代碼向es5代碼的轉換,首先須要安裝babel核心程序,及babel-loader
npm install babel-loader babel-core
在使用babel-loader進行代碼轉換以前,要先了解到ecmascript標準變化很快,且瀏覽器支持狀況不一樣。因此,出現了'es2015'、'es2016'、'es2017'、'latest'、'env(new)'等多個不一樣的標準。這時,要須要來選擇從哪一個標準進行轉換,須要安裝插件babel-preset-env
npm install babel-preset-env
在 webpack 配置對象中,須要添加 babel-loader 到 module 的 loaders 列表中。webpack的配置文件以下所示
const path = require('path');
module.exports = { entry:{ app:'./src/app.js', }, output:{ path:path.resolve(__dirname,'src'), filename: '[name].bundle.js' }, module: { rules: [{ test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['env'] } } }] }, }
關於path有兩種寫法,除了上面的配置文件的寫法外,另外一種寫法以下所示。可是,儘可能不要使用__dirname + '/src'的寫法,在某些參數中,該寫法沒法生效
path: __dirname + "/src"
在命令行中運行webpack命令進行打包,打包過程以下
打包前的文件爲app.js,內容以下
() => {
return a + b; }; Array.from('1,2,3'); new Set;
打包後的文件爲app.bundle.js,主要內容以下
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) { "use strict"; (function () { return a + b; }); Array.from('1,2,3'); new Set(); /***/ }) /******/ ]);
通過babel轉換後的js文件存在兩個問題:
一、打包速度較慢
二、部分ES2017的新語法沒有轉換爲ES5的代碼
下面對這兩個問題分別進行處理
【打包速度】
loader的test屬性表示該loader必須知足的條件,上面代碼中使用/\.js$/ 來匹配,也許會去編譯 node_modules 目錄或者其餘不須要的源代碼。這樣會大大增長webpack的編譯時間
要排除 node_modules,就要使用 loaders 配置的 exclude 選項,表示哪些除外,exclude:/node_modules/
module.exports = {
entry:{
app:'./src/app.js', }, output:{ path:__dirname+'/src/', filename: '[name].bundle.js' }, module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['env'] } } }] }, }
[注意]exclude除了支持正則表達式外,還支持字符串形式,寫法以下。若是用__dirname +'/node_modules'的形式則不會生效
const path = require('path');
exclude:path.resolve(__dirname, "node_modules")
打包過程以下
當node-modules文件部分較大時,速度提高會更明顯
除了exclude選項,還可使用include選項,可以明確被打包的文件時,使用include將使打包速度更快
module.exports = {
entry:{
app:'./src/app.js', }, output:{ path:__dirname+'/src/', filename: '[name].bundle.js' }, module: { rules: [{ test: /\.js$/, include: /src/, use: { loader: 'babel-loader', options: { presets: ['env'] } } }] }, }
[注意]include的另外一種寫法以下所示
const path = require('path');
include: path.resolve(__dirname, 'src')
打包過程以下
耗費時間有所減少
cacheDirectory選項值默認爲false,當爲true時,指定的目錄將用來緩存 loader 的執行結果。以後的 webpack 構建,將會嘗試讀取緩存,來避免在每次執行時,可能產生的、高性能消耗的 Babel 從新編譯過程
const path = require('path');
module.exports = { entry: { app: './src/app.js', }, output: { path: path.resolve(__dirname, 'src'), filename: '[name].bundle.js' }, module: { rules: [{ test: /\.js$/, include: path.resolve(__dirname, 'src'), use: { loader: 'babel-loader', options: { presets: ['env'], cacheDirectory:true } } }] }, }
耗費時間減小了100ms,效果很好
解決了babel編譯速度後,下面來解決ES新語法不被轉換的問題
【babel-polyfill】
Babel默認只轉換新的JavaScript句法(syntax),而不轉換新的API,好比Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局對象,以及一些定義在全局對象上的方法(好比Object.assign
)都不會轉碼。
舉例來講,ES6在Array
對象上新增了Array.from
方法。Babel就不會轉碼這個方法。若是想讓這個方法運行,必須使用babel-polyfill。
babel-polyfill是一個全局墊片,爲開發應用準備的
npm install babel-polyfill
在腳本頭部加入下面代碼便可使用
import 'babel-polyfill';
app.js的文件內容以下
import 'babel-polyfill';
() => { return a + b; }; Array.from('1,2,3'); new Set;
由下圖所示,轉換後的文件大小超過了200kb
【babel-plugin-transform-runtime】
至關於babel-polyfill來講,babel-plugin-transform-runtime更加適用,它是一個局部墊片,爲開發框架準備
npm install babel-plugin-transform-runtime babel-runtime
app.js文件以下所示
() => {
return a + b; }; Array.from('1,2,3'); new Set;
配置文件以下所示
const path = require('path');
module.exports = { entry: { app: './src/app.js', }, output: { path: path.resolve(__dirname, 'src'), filename: '[name].bundle.js' }, module: { rules: [{ test: /\.js$/, include: path.resolve(__dirname, 'src'), use: { loader: 'babel-loader', options: { presets: ['env'], cacheDirectory:true, plugins: ['transform-runtime'] } } }] }, }
轉換過程以下所示
轉換後的文件app.bundle.js主要內容以下所示
(function () {
return a + b; }); (0, _from2.default)('1,2,3'); new _set2.default();
在webpack入門博文中由介紹過CSS插件的簡單使用,接下來將詳細介紹
首先,要安裝css-loader和style-loader,css-loader用於讀取並加載css文件,style-loader將它插入到頁面中
[特別注意]在處理css時,最好不要使用include、exclude等屬性。include、exclude屬性是加快babel轉換速度的,和css沒什麼關係,並且會添亂
npm install css-loader style-loader
//app.js require('./css/common.css'); //common.css body{margin: 0;background-color: red} //webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/app.js', output:{ path: __dirname,//出口路徑 filename: 'js/[name].bundle.js'//出口名稱 }, module:{ rules:[ { test:/\.css$/, use:[ 'style-loader', 'css-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({}) ] }
效果以下
【自動前綴】
頁面加載CSS每每並不像上面的狀況這麼簡單,須要處理不少問題,其中一個就是瀏覽器前綴問題。對於某些屬性來講,好比transform,不一樣瀏覽器的版本對其支持程度不一樣,瀏覽器前綴也不一樣。這時,就須要可以根據實際狀況,自動增長前綴,而postcss-loader就是這樣的工具,並且功能要強大的多
首先,先安裝postcss-loader
npm install postcss-loader
而後,安裝postcss的自動前綴的插件autoprefixer
npm install autoprefixer
配置以下
//common.css body{transform: scale(0);background-color: red} //app.js require('./css/common.css'); //webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/app.js', output:{ path: __dirname,//出口路徑 filename: 'js/[name].bundle.js'//出口名稱 }, module:{ rules:[ { test:/\.css$/, use:[ 'style-loader', 'css-loader', { loader: 'postcss-loader', options: {plugins: [require('autoprefixer')]} } ] } ] }, plugins: [ new HtmlWebpackPlugin({}) ] }
結果以下
若是css文件中出現@import,則有兩種處理方式,一種是將postcss文件單獨寫成配置文件postcss.config.js
//common.css @import './flex.css'; body{transform: scale(0);background-color: red} //flex.css body{display:flex;} //app.js require('./css/common.css'); //webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/app.js', output:{ path: __dirname,//出口路徑 filename: 'js/[name].bundle.js'//出口名稱 }, module:{ rules:[ { test:/\.css$/, use:[ 'style-loader', { loader: 'css-loader', options: {importLoaders: 1} }, 'postcss-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({}) ] } //postcss.config.js module.exports = { plugins:[require('autoprefixer')] }
結果以下
另外一種須要安裝postcss-import插件
npm install postcss-import
//common.css @import './flex.css'; body{transform: scale(0);background-color: red} //flex.css body{display:flex;} //app.js require('./css/common.css'); //webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/app.js', output:{ path: __dirname,//出口路徑 filename: 'js/[name].bundle.js'//出口名稱 }, module:{ rules:[ { test:/\.css$/, use:[ 'style-loader', { loader: 'css-loader', options: {importLoaders: 1 } }, { loader: 'postcss-loader', options: {plugins: [ require('postcss-import'), require('autoprefixer') ] } } ] } ] }, plugins: [ new HtmlWebpackPlugin({}) ] }
結果以下
【sass】
首先,須要安裝sass-loader及node-sass
[注意]關於node-sass安裝的問題移步至此
npm install sass-loader node-sass
因爲sass-loader中已經自帶了關於@import處理的問題。因此,不須要css-loader及postcss-loader的額外處理
//layer.scss @import './flex.scss'; body{ background-color:green; div{ width: 400px; } } //flex.scss .flex{display:flex;} //app.js require('./components/layer/layer.scss'); //webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/app.js', output:{ path: __dirname,//出口路徑 filename: 'js/[name].bundle.js'//出口名稱 }, module:{ rules:[ { test:/\.scss$/, use:[ 'style-loader', 'css-loader', { loader: 'postcss-loader', options: {plugins: [require('autoprefixer')]} }, 'sass-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({}) ] }
結果以下
【分離CSS】
默認地,CSS做爲模塊資源被打包到入口js文件中。有時,須要把CSS文件分離出來,這時就須要用到extract-text-webpack-plugin插件
npm install extract-text-webpack-plugin
該插件的配置以下
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: './src/app.js', output:{ path: __dirname,//出口路徑 filename: 'js/[name].bundle.js'//出口名稱 }, module:{ rules:[ { test:/\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use:[ 'css-loader', { loader: 'postcss-loader', options: {plugins: [require('autoprefixer')]} }, 'sass-loader' ] }) } ] }, plugins: [ new HtmlWebpackPlugin({}), new ExtractTextPlugin("styles.css") ] }
結果以下,該插件將入口文件中引用的 *.css,移動到獨立分離的 CSS 文件。所以,你的樣式將再也不內嵌到 JS bundle 中,而是會放到一個單獨的 CSS 文件(即 styles.css)當中。 若是樣式文件大小較大,這會作更快提早加載,由於 CSS bundle 會跟 JS bundle 並行加載
webpack在處理圖片、音樂、電影等資源文件時,須要使用file-loader
npm install file-loader
默認狀況下,使用file-loader生成的文件的文件名就是文件內容的MD5哈希值並保留原始擴展名
file-loader的配置項以下所示
name [hash].[ext] 爲文件配置自定義文件名模板 context this.options.context 配置自定義文件 context,默認爲 webpack.config.js context publicPath __webpack_public_path__ 爲文件配置自定義 public 發佈目錄 outputPath 'undefined' 爲文件配置自定義 output 輸出目錄 useRelativePath false 若是但願爲每一個文件生成一個相對 url 的 context 時,應該將其設置爲 true emitFile true 默認狀況下會生成文件,能夠經過將此項設置爲 false 來禁止(例如,使用了服務端的 packages)
以引入圖片資源例,有如下幾種狀況
一、經過css文件的background屬性引入
//webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, module:{ rules:[ { test:/\.css$/, use:[ 'style-loader', 'css-loader' ] }, { test:/\.(png|jpg|gif|svg)$/i, use:'file-loader' } ] }, plugins: [ new HtmlWebpackPlugin() ] } //entry.js require('./src/css/common.css'); //common.css body{background: url('../img/eg_bulbon.gif')}
結果以下
二、經過模板html文件img標籤引入,這時須要使用${require('')}將相對路徑包裹一次
//webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname,//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, module:{ rules:[ { test:/\.css$/, use:[ 'style-loader', 'css-loader' ] }, { test:/\.(png|jpg|gif|svg)$/i, use:'file-loader' } ] }, plugins: [ new HtmlWebpackPlugin({ template:'template/template.html' }) ] } //template.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <img src="${require('../src/img/eg_bulbon.gif')}" alt=""> </body> </html>
結果以下
三、若模板使用ejs-compiled-loader插件,則沒法使用${require('')}語句,須要使用HtmlWebpackPlugin傳參來構造絕對路徑
//webpack.config.js var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './entry.js', //入口文件 output: { path: __dirname + '/dist',//出口路徑 filename: 'js/[id]-[name]-[hash].js'//出口名稱 }, module:{ rules:[ { test:/\.css$/, use:[ 'style-loader', 'css-loader' ] }, { test:/\.(png|jpg|gif|svg)$/i, use:'file-loader' } ] }, plugins: [ new HtmlWebpackPlugin({ template:'ejs-compiled-loader!template/template.html', file:__dirname }) ] } //template.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div> <% include template/header.html %> </div> </body> </html> //header.html <img src="<%=htmlWebpackPlugin.options.file%>\src\img\eg_bulbon.gif" alt="">
結果以下
【file-loader參數】
文件名模板佔位符有以下幾種
[ext] 資源擴展名 [name] 資源的基本名稱 [path] 資源相對於 context 查詢參數或者配置的路徑 [hash] 內容的哈希值,默認爲十六進制編碼的 md5 [<hashType>:hash:<digestType>:<length>] 可選配置 其餘的 hashType, 即 sha1, md5, sha256, sha512 其餘的 digestType, 即 hex, base26, base32, base36, base49, base52, base58, base62, base64 length 字符的長度 [N] 當前文件名按照查詢參數 regExp 匹配後得到到第 N 個匹配結果
{ test:/\.(png|jpg|gif|svg)$/i, use:[{ loader:'file-loader', options: { name:'[name]-[hash:5].[ext]' } }] }
或者
{ test:/\.(png|jpg|gif|svg)$/i, use:['file-loader?name=[name]-[hash:5].[ext]'] }
結果以下
【url-loader】
url-loader功能相似於file-loader,可是在文件大小(單位byte)低於指定的限制時,能夠返回一個dataURL
能夠經過傳遞查詢參數(query parameter)來指定限制(默認爲不限制)
若是文件大小超過限制,將轉爲使用 file-loader,全部的查詢參數也會傳過去
npm install url-loader
圖片的大小爲1.1kb,下面將限制設置爲2000,則圖片將以base64格式傳遞
{ test:/\.(png|jpg|gif|svg)$/i, use:['url-loader?limit=2000'] }
結果以下
若是將限制大小設置爲1000,圖片以src的形式傳遞
{ test:/\.(png|jpg|gif|svg)$/i, use:[{ loader:'url-loader', options: { limit:1000, name:'[name]-[hash:5].[ext]' } }] }
【image-webpack-loader】
使用image-webpack-loader來壓縮圖片
npm install image-webpack-loader
image-webpack-loader的配置項以下
options: {
mozjpeg: {
progressive: true, quality: 65 }, optipng: { enabled: false, }, pngquant: { quality: 80, speed: 4 }, gifsicle: { interlaced: false, }, webp: { quality: 75 } }
插件一張大小爲4.1kb的名稱爲'm.jpg'的圖片,配置以下
{ test:/\.(png|jpg|gif|svg)$/i, use:[ 'url-loader?limit=1000&name=[name]-[hash:5].[ext]', 'image-webpack-loader' ] }
結果以下所示,生成大小爲3.28kb,名稱爲'm-c7083.jpg'的圖片
【雪碧圖】
在webpack中自動生成雪碧圖,須要使用postcss-sprits插件
npm install postcss-sprites
配置很是簡單
"plugins": { "postcss-sprites": { spritePath: 'dist/assets/imgs/sprites/' } } }
若是是加載的遠程CDN庫,則在HTML文件內直接使用script標籤引入便可
<script src="https://cdn.bootcss.com/jquery/3.3.1/core.js"></script>
這樣,在文件中能夠直接使用jQuery
若是jQuery是經過npm保存到本地,則須要使用ProvidePlugin插件來自動加載模塊,而沒必要處處 import
或 require
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })
而後在咱們任意源碼中:
// in a module $('#item'); // <= 起做用 jQuery('#item'); // <= 起做用 // $ 自動被設置爲 "jquery" 輸出的內容
若是jQuery是保存在一個自定義的目錄中的,則須要還須要設置別名
resolve:{ alias:{ jquery$:path.resolve(__dirname,'src/libs/jquery.min.js') } }
除了使用providePlugin,還可使用imports-loader
module: { rules: [ { test: path.resolve(__dirname,"src/app.js"), use: [ loader: 'imports-loader', options: {$:'jquery'} ] } ] }
使用webpack-dev-server的proxy功能,能夠代理遠程接口。實際上,它使用的是http-proxy-middleware插件
經常使用參數以下
target:代理指向的地址
changeOrigin:改變源URL(默認false)
headers:設置http請求頭
pathRewrite:重定向接口請求
logLevel:控制檯顯示信息
在 localhost:3000
上有後端服務的話,能夠這樣啓用代理:
proxy: { "/api": "http://localhost:3000" }
若是服務器給出500錯誤,則須要添加changeOrigin
proxy: { "/api": { target: "http://localhost:3000", changeOrigin: true } }
下面將使用webpack搭建一個實用的開發環境
var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: './src/app.js',//入口文件 output:{ path: __dirname,//出口路徑 filename: 'js/[name].bundle.js'//出口名稱 }, module:{ rules:[ { test:/\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use:[ 'css-loader', { loader: 'postcss-loader', //自動添加前綴 options: {plugins: [require('autoprefixer')]} }, 'sass-loader' ] }) }, { test:/\.js$/, include:/\.\/src/, use:{ loader: 'babel-loader', //將最新標準的js代碼翻譯爲es5代碼 options:{presets: ['env']} } }, { test:/\.(png|jpg|gif|svg)$/i, use:[ //當圖片大小大於1000byte時,以[name]-[hash:5].[ext]的形式輸出 //當圖片大小小於1000byte時,以baseURL的形式輸出 'url-loader?limit=1000&name=[name]-[hash:5].[ext]', //壓縮圖片 'image-webpack-loader' ] } ] }, plugins: [ //使用模板生成html文件 new HtmlWebpackPlugin({template:'ejs-compiled-loader!template/template.html'}), //分離出css到style.css new ExtractTextPlugin("style.css") ] }