webpack實用配置

開車以前,先介紹一些npm的命令:

:D
進入D盤javascript

mkdir webappcss

建立webapp文件夾

cd webapphtml

進入webapp文件夾

mkdir webapp && cd webappvue

以上兩步建立和進入文件夾能夠合併爲一步

npm init -yjava

快速生成package.json文件

npm install xxx --save-devnode

//安裝模塊並加入到開發依賴中,好比webpack

npm install xxx --savejquery

安裝模塊並加入到生產依賴中,好比Jquery

npm install xxx@2.3.0webpack

下載指定版本

npm view webpack versions --jsongit

若是忘記版本號,能夠列出全部版本號

npm install -g cnpm --registry=https://registry.npm.taobao.orges6

下載淘寶鏡像源,國內npm下載很慢,並且有些包下下來貌似會有問題,好比node-sass。

下載以後就能夠直接使用了,使用方式跟Npm同樣,只不過是改爲cnpm

cls

清空命令提示符窗口內容




webpack

1. html篇

介紹完npm基本的東西后,下面開始擼webpack

有關webpack的基本概念建議到官網查看,解釋的更爲清楚,下面只簡單介紹。

1.  在根目錄下生成package.json文件: npm init -y 2. 安裝webapck cnpm install webpack --save-dev 3. 建立webpack.config.js文件: echo > webpack.config.js
var path=require("path"); module.exports={ <!-- 要打包的文件 --> entry:"./index.js", output:{ <!-- 指定打包後的文件名字 --> filename:"bundle.js", <!-- 打包後的文件路徑 --> path:path.resolve(__dirname,"dist") } }
4.建立src目錄,並在src目錄下建立index.html, index.js文件並隨便輸一點東西
window.onload=function(){ alert(1) } 
5.執行 webpack 命令,能夠發現webpack幫咱們在dist下生成了一個main.js文件,打開main.js並拖到最下面你會發現index.js的內容就在裏面。 打包完以後,咱們在dist生成了js文件,可是咱們的index.html在src下面,你能夠手動的複製src下的html文件到dist目錄下,而且將打包後的js文件引入。不過像咱們這麼懶的人,仍是但願webpack可以幫咱們在dist下也生成index.html,要是能自動引入打包後的js文件,那就再好不過了。這時候,是時候來一發插件了。 6.cnpm install html-webpack-plugin --save-dev
修改webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin'); var path = require("path") module.exports = { entry:"./index.js", output: { path: path.resolve(__dirname, 'dist'), filename:"bundle.js", }, plugins: [new HtmlWebpackPlugin({ title: "測試" })] };
從新執行命令 webpack ,你會發如今dist下多生成了一個index.html文件,打開發現還有一個script的標籤引用着咱們打包後的文件,nice。 不過問題又來了,html文件很簡陋,就是emmet幫咱們生成的Html5文件,你可能但願還帶有更多的 meta標籤,像這樣的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="format-detection" content="telephone=no, email=no"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> </head> <body> <header></header> <nav></nav> <div id="app"></div> <footer></footer> </body>
此時,你能夠本身寫一個模板,只須要告訴html-webpack-plugin插件文件的位置就能夠了。
修改webpack.config.js
plugins: [ new htmlWebpackPlugin({ title:"首頁", <!-- 指定模板位置 --> template:'./src/index.html', <!-- 指定打包後的文件名字 --> filename: 'index.html' }) ]
對於多疑症的你,打包屢次後你可能會懷疑文件修改生效了沒有,此時你能夠安裝clean-webpack-plugin插件,在每次打包時,先刪除原來的dist目錄,再從新打包,這樣就能夠放心的睡覺,不用擔憂門沒關了。
7.cnpm install clean-webpack-plugin --save-dev
plugins:[ new htmlWebpackPlugin({ title:"首頁", template:'./src/index.html', filename: 'index.html' }), <!-- 每次打包前先刪除dist目錄 --> new CleanWebpackPlugin(['dist']) ]

css篇

 

以往咱們寫css都是寫好後手動經過link引入到html,使用webpack後,你將再也不須要手動作這些操做,只須要在js文件中引入,webpack就能幫你搞定,不過須要一些loader和plugin的支持。

cnpm install --save-dev css-loade style-loader

修改webpack.config.js
###爲了處理css文件咱們須要多配置一個module參數,並使用css-loader來將css文件打包到成「字符串」到js文件中,並使用style-loader將打包後的字符串提取出來並append<style>標籤到head下面 var path=require("path"); var htmlWebpackPlugin=require('html-webpack-plugin'); var CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports={ entry:{ main:'./src/index.js' }, output:{ filename:"bundle.js", path:path.resolve(__dirname,'dist') }, module:{ rules:[ <!-- test檢測到以xxx結尾的東西use對應的loader --> { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] } ] }, plugins:[ new htmlWebpackPlugin({ title:"首頁", template:'./src/index.html', filename:"index.html" }), new CleanWebpackPlugin(['dist']) ] }
哦,據說你想用sass 預處理 器,那麼只須要在use里加多一個sass-loader,並安裝依賴
cnpm install --save-dev sass-loader node-sass rules:[ { test: /\.scss$/, use: [ 'style-loader', 'css-loader',"sass-loader" ] } ]
什麼,想要自動補全瀏覽器後綴autoprefixer?沒問題
cnpm install --save-dev postcss-loader rules:[ { test: /\.s?css$/, use: [ { loader: "style-loader" }, { loader: "css-loader" }, { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer')({ browsers: ['last 10 versions'] }) ] } }, { loader: "sass-loader" } ] } ]

這裏須要注意,use裏面的執行順序是倒序的 ,,webpack會以倒敘的方式處理並將處理後的結果返回給上一個loader,最後經過style-loader將文件的內容append到head下面的style標籤裏。

教練,我還想要自動刷新

當你修改一點文件後,你須要重執行命令新編譯文件,而後刷新頁面。若是你使用過gulp的自動刷新好比live-reload,那你也必定但願webpack也有一樣的功能,webpack-dev-server知足你的需求而且可以給你更多。

安裝webpack-dev-server到開發依賴  cnpm install --save-dev webpack-dev-server
<!-- 在package.json中加入: --> "scripts": { "dev": "webpack-dev-server" }
經過npm run dev便可執行建立一個服務器,打開localhsot:8080
此時再修改文件,你會發現頁面自動刷新了而且修改生效了,不過你看不到從新編譯後的文件在哪裏,應爲webpack-dev-server將文件編譯到了內存中 ,比起從新生成文件效率會更高,固然只適用於開發階段。
啓動服務後,若是你 還想讓他本身 打開Localhost,還想 使用模塊熱重載 ,能夠加多一個配置
devServer:{ open:true, hot: true,// 告訴 dev-server咱們想用HMR模式 }
開發的時候咱們並不在乎 style這種形式,可是咱們但願在生產環境下 css能從js文件宏分離出來,咱們但願能css能跟js並行加載,並且能夠避免由於Js文件過大,加載慢而產生的flash of unstyle(無樣式頁面閃爍)。
使用「extract-text-webpack-plugin」插件來分離css代碼。 

修改webpack.config.js

cnpm install --save-dev extract-text-webpack-plugin
var path=require("path"); var webpack=require('webpack'); var htmlWebpackPlugin=require('html-webpack-plugin'); var CleanWebpackPlugin = require('clean-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); var extractSass = new ExtractTextPlugin({ filename: "[name].[contenthash].css", disable: process.env.NODE_ENV === "development" }); //經過設置環境變量來告訴webpack咱們在development模式下不須要提取css到單獨在文件,只有當不是development下(也便是production)才須要提取文件。 module.exports={ entry:{ main:'./src/index.js' }, output:{ filename:"bundle.js", path:path.resolve(__dirname,'dist') }, devServer:{ open:true, hot: true, <!-- 告訴 dev-server咱們想用HMR模式 --> }, module:{ rules:[ { test: /\.s?css$/, use: extractSass.extract({ use: [ { loader: "css-loader" }, { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer') ] } }, { loader: "sass-loader" }], fallback: "style-loader" }) } ] }, plugins:[ <!-- 使用此插件來支持熱重載 --> new webpack.HotModuleReplacementPlugin(), new htmlWebpackPlugin({ title:"首頁", template:'./src/index.html', filename:"index.html" }), new CleanWebpackPlugin(['dist']), extractSass ] }

修改package.json ,本人爲window10系統

"scripts": { "dev": "set NODE_ENV=development&&webpack-dev-server", "build":"webpack -p" }
分別執行npm run dev以及npm run build,你會發先npm run build時css文件被提取到一個單獨的文件了。

 

js篇

--------------------------------好累啊下面直接上代碼了

爲了使用promise,async等es6,7語法,同時兼容低版本瀏覽器,你還須要將js轉碼爲es5。

你須要安裝如下依賴包
cnpm install --save-dev "babel-core": "^6.25.0", "babel-loader": "^7.0.0", "babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.5.2", 在module下增長: { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['env'], plugins: ['transform-runtime'] } } }

寫一點async或者prmise代碼,打包後發現promise變成了_promise2

 

代理



先後端分離開發時常常還會遇到跨域的問題,還能夠利用devServer來進行代理

devServer:{ open:true, hot: true, proxy: { '/api/': { target: 'http://baidu.com', secure: false, changeOrigin: true } } $.ajax({ url:'/api/', success:function(res){ console.log(res) }, error:function(res){ console.log(res) } })

圖片,字體篇

{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', query: { limit: 8000, <!-- 小於8k的轉化爲Base64 --> name: '[name].[hash:7].[ext]' } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', query: { limit: 8000, name: 'font/[name].[hash:7].[ext]' } }
你可能想要把全部img或者font文件分別放到一個img或者font文件夾下,能夠這麼寫:name: 'img/[name].[hash:7].[ext]' 

 

若是你不想下載字體文件下來,可已上傳到阿里字體庫並使用阿里的在線字體圖標,並複製本身的文件的在線地址。

 

在css裏面像這麼用:@import url("//at.alicdn.com/t/font_s0zqwb6by3lhm2t9.css"); 

打包多文件

var path=require("path"); var webpack=require('webpack'); var htmlWebpackPlugin=require('html-webpack-plugin'); var CleanWebpackPlugin = require('clean-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); var extractSass = new ExtractTextPlugin({ filename: "[name].[contenthash].css", disable: process.env.NODE_ENV === "development" }); module.exports={ entry:{ "main":'./src/js/index.js', "car":"./src/js/car.js", "goods":"./src/js/goods.js" }, output:{ filename:"[name].[hash].js", path:path.resolve(__dirname,'dist') }, devServer:{ open:true, hot: true, proxy: { '/api/': { target: 'http://baidu.com', secure: false, changeOrigin: true } } }, module:{ rules:[ { test: /\.s?css$/, use: extractSass.extract({ use: [ { loader: "css-loader" }, { loader: 'postcss-loader', options: { plugins: [ require('autoprefixer')({ browsers: ['last 10 versions'] }) ] } }, { loader: "sass-loader" }], fallback: "style-loader" }) }, { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['env'], plugins: ['transform-runtime'] } } }, {       test: /\.html$/,       use: ['html-withimg-loader']     }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', query: { limit: 8000, name: 'img/[name].[hash:7].[ext]' } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', query: { limit: 8000, name: 'font/[name].[hash:7].[ext]' } } ] }, plugins:[ new webpack.HotModuleReplacementPlugin(), new htmlWebpackPlugin({ title:"首頁", template:'./src/index.html', filename:"index.html", chunks:["page/main/main"] }), new htmlWebpackPlugin({ title:"購物車", template:'./src/index.html', filename:"car.html", chunks:["page/car/car"] }), new htmlWebpackPlugin({ title:"商品", template:'./src/index.html', filename:"goods.html", chunks:["page/goods/goods"] }), new CleanWebpackPlugin(['dist']), extractSass, new webpack.ProvidePlugin({ $:"jquery", jQuery:"jquery" }) ] }
上面這樣寫打包後文件都放在一個目錄下,目錄很亂,不方便管理,想讓每一個頁面的js,css文件放在對應目錄下,能夠按下面這麼寫
entry:{ "page/main/main":'./src/js/index.js', "page/car/car":"./src/js/car.js", "page/goods/goods":"./src/js/goods.js" }
若是多個文件都引用了一些其餘庫,好比Jquery,vue,你可能想把全部的公共庫提取出來,利用common-chunk插件能夠解決。即便你作的是spa單頁面應用,你也能夠將公共庫從js文件中提取出來,每次修改時只修改業務邏輯而不從新打包庫,從而能夠緩存庫文件。
entry:{ "main/main":'./src/js/index.js', "car/car":"./src/js/car.js", "goods/goods":"./src/js/goods.js" "vendor":["jquery","vue"] }, plugins:[ new htmlWebpackPlugin({ ...同上 chunks:["page/main/main","vendor","mainfest"] }), new htmlWebpackPlugin({ ... chunks:["page/car/car","vendor","mainfest"] }), new htmlWebpackPlugin({ ... chunks:["page/goods/goods","vendor","mainfest"] }), new webpack.optimize.CommonsChunkPlugin({ name:["vendor","mainfest"] }) ]
發現一個問題,在公司電腦dev-server-open自動打開的地址後面會帶undefined,去掉undefined打開網址才正常

 

代碼文件能夠上github查看

https://github.com/linrunzheng/webpackGuide

經常使用的配置就這樣了,其餘配置能夠去webpack官網看。若是以爲本文對你有所幫助,麻煩點個start或者贊

webpack3都出了,你還不會2嗎?

 

 

前面的話

  上文介紹了webpack入門,本文將詳細介紹webpack實用配置

 

版本號

  以entry.js打包爲bundle.js爲例,出口的filename能夠設置爲[id]、[name]、[hash]、[chunkhash]等替換形式,以下所示

複製代碼
var webpack = require('webpack');
module.exports = {
  entry: './entry.js', //入口文件
  output: {
    path: __dirname,//出口路徑
    filename: '[id]-[name]-[hash].js'//出口名稱
  }
}
複製代碼

  則出口文件爲0-main-0c1dce21f6c5db455fb4.js

  若是index.html要引用打包後的js文件,因爲文件名稱不肯定,並很差解決。這時,就須要使用html-webpack-plugin插件。該插件並非內置插件,因此須要安裝

npm install html-webpack-plugin

  HtmlWebpackPlugin簡化了HTML文件的建立,以便爲webpack包提供服務。這對於在文件名中包含每次會隨着變異會發生變化的哈希的webpack bundle尤爲有用

複製代碼
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不存在,則生成;若是存在,則替換

  [注意]若是htmlwebpackplugin不進行配置,參數爲空, plugins: [new HtmlWebpackPlugin()]。默認地,生成的html文件名稱爲'index.html',標題爲'Webpack APP' 

【標籤位置】

  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'
    })
  ]
}
複製代碼

【圖標設置】

  設置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

  下面使用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.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:{
      loaders:[{
          test:/\.js$/,
          use:{
              loader:'babel-loader',
              options:{
                  presets: ['env']
              }
          }
      }]
  },
  plugins: [
    new HtmlWebpackPlugin({})
  ]
}
複製代碼
//app.js
let num = 1;
console.log(num);

【打包速度】

  運行後,頁面控制檯輸出1,轉換正常。可是,babel的轉換過程卻很慢

  前面的博文webpack的四個基本概念,咱們介紹過loader的test屬性表示該loader必須知足的條件,上面代碼中使用/\.js$/ 來匹配,這樣也許會去轉譯 node_modules 目錄或者其餘不須要的源代碼。這樣會大大增長webpack的編譯時間

  要排除 node_modules,就要使用 loaders 配置的 exclude 選項,表示哪些除外,exclude:/node_modules/

  [注意]exclude也應該用正則的形式,若是用__dirname +'/node_modules'的形式則不會生效

複製代碼
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:{
      loaders:[{
          test:/\.js$/,
          exclude: /node_modules/,
          use:{
              loader: 'babel-loader',
              options:{
                  presets: ['env']
              }
          }
      }]
  },
  plugins: [
    new HtmlWebpackPlugin({})
  ]
}
複製代碼

  固然了,除了exclude選項,也有include選項,可以明確被打包的文件時,使用include將使打包速度更快

  對於include來講,它比較特別,字符串形式__dirname + './src/'和正則形式/\.\/src/都支持,通過測試,這兩種形式的打包速度相似

複製代碼
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:{
      loaders:[{
          test:/\.js$/,
          include:/\.\/src/,
          use:{
              loader: 'babel-loader',
              options:{
                  presets: ['env']
              }
          }
      }]
  },
  plugins: [
    new HtmlWebpackPlugin({})
  ]
}
複製代碼

 

CSS

  在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哈希值並保留原始擴展名

  以引入圖片資源例,有如下幾種狀況

  一、經過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

  插件一張大小爲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搭建一個實用的開發環境

複製代碼
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")
    ]
}
相關文章
相關標籤/搜索