上一篇文章講述瞭如何安裝和配置webpack的基礎依賴,能夠看連接描述javascript
這篇文章咱們來看看如何配置webpack最重要的配置文件webpack.config.jscss
首先咱們先在根目錄下新建一個webpack.config.js,而後開始配置
首先咱們須要寫一個moudle.exports={},咱們全部的配置項都須要在這裏面配置,包括entry(文件入口),output(文件出口),module(裏面配置一些loader)等等
具體代碼以下html
module.exports = { entry:'./src/js/index.js',//入口文件 output:{ filename:'layer.js', //輸出的文件名 path : __dirname + '/dist' //輸出文件路徑 }, }
其中entry是咱們要打包的js文件,output是咱們打包以後的js文件,filename是打包後的文件名,path是咱們的輸出路徑,其中__dirname 表示當前路徑。
好了,咱們在src(和webpack.config.js以及package.json同級)目錄下建立一個js文件夾,而後在其中新建一個index.js,裏面隨便寫上一點什麼,在這裏我是寫了一個alert,而後咱們執行打包操做
在命令行中進入當前項目的路徑,而後輸入java
webpack --mode development
在4.0版本以前咱們可使用webpack來執行打包,可是在4.0以後,webpack分紅了開發環境和生產環境,webpack --mode development表示的開發環境下的打包, webpack --mode production表示是在實際項目上線時執行的打包。
那麼咱們打包以後的結果以下圖:node
打包成功,而後咱們發如今根目錄下出現了一個dist文件夾,而且裏面出現了一個打包好的layer.js文件。
而後咱們新建一個layer.html文件,引入打包好後的layer.js,發現能達到和index.js同樣的效果
代碼以下:
layer.html:webpack
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script type="text/javascript" src="dist/layer.js" ></script> </body> </html>
index.jses6
alert('webpack');
這代表咱們能夠正常打包了。web
強大的webapck loader功能
光是js的打包並不能知足咱們的要求,咱們在實際開發中也須要引用和打包一些其餘的文件,好比less,sass,css,圖片等等,因此咱們須要配置一些loader來完成這些文件的打包。npm
首先咱們先來看看js的loader吧,如今不少js都是用es6來寫的,咱們須要用webpack使他變成瀏覽器能識別的es5代碼。
首先咱們須要在項目根目錄下安裝一個babel-loader,經過這個包將es6代碼轉換爲es5代碼json
npm install babel-loader --save-dev npm install babel --save-dev npm install babel-core --save-dev
而後咱們在webpack.config.js新增一個module,而後在裏面配置babel-loader,代碼以下:
module.exports = { entry:'./src/js/index.js',//入口文件 output:{ filename:'layer.js', //輸出的文件名 path : __dirname + '/dist' //輸出文件路徑 }, module:{ rules:[ { test:/.js$/, use:[ {loader:'babel-loader'} ] } ] }, }
在這之中我使用了webapck4的use來導入loader,固然也可使用webpack4如下的loaders來導入loader,webpack4對於這兩種導入方式都支持。
而後咱們打包一下就能夠將es6的代碼轉換成瀏覽器能夠識別的es5代碼了
接下來是比較重要的css-loader了,這個咱們須要下的包就有些多了
下面是須要安裝的包,咱們一次性安裝無缺了
npm install css-loader style-loader postcss-loader autoprefixer --save-dev
而後咱們在rules裏面進行配置
代碼以下:
module.exports = { entry:'./src/js/index.js',//入口文件 output:{ filename:'layer.js', //輸出的文件名 path : __dirname + '/dist' //輸出文件路徑 }, module:{ rules:[ { test:/.js$/, use:[ {loader:'babel-loader'} ] }, { test: /.css$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } } ] }/*解析css, 並把css添加到html的style標籤裏*/ ] }, }
其中css-loader是解析css文件的,style-loader是將css文件經過style的方式去引入,在css-loader中咱們經過options給css-loader額外配置了一個importLoaders參數,這個參數表示在css-loader以後指定幾個數量的loader來處理import進來的資源,這裏設定爲1。
postcss是用來作css瀏覽器兼容的,這個loader必需要配置options,不然在打包的時候就會報錯No PostCSS Config found,在這個options中咱們引用了以前安裝的autoprefixer,這個是用來自動匹配瀏覽器來補全前綴的,而後咱們設置爲最近五個瀏覽器版本。注意這些loader的排序方式不能改變,必須是style-loader在css-loader以前,css-loader在postcss-loader以前,這是由於webpack的數組是從後往前解析的。
而後咱們在src文件夾下面創建一個css文件夾,在裏面創建layer.css文件,寫一些樣式進去,而後在index.js文件中,經過commonjs的方式去引入這個css文件,具體代碼以下
layer.css
.test1{ width: 100px; height: 100px; background: blue; }
index.js
require('../css/layer.css'); const a = "webapck"; alert(a);
打包以後,運行效果如圖所示
代表咱們的css文件也成功打包了
接下來是圖片的解析,咱們也須要安裝一些loader,代碼以下:
npm install url-loader file-loader --save-dev
一樣的咱們須要在rules中去配置這個loader,具體配置代碼以下:
{ test: /.(jpg|png|gif|svg)$/, use: [ { loader:'url-loader', options:{ limit: 500,//圖片小於500的話就把圖片轉爲base64格式 outputPath: 'assets/images/', name: '[hash].[ext]', } } ] }
在這個配置中咱們能夠識別以jpg,png,gif,svg爲後綴名的圖片,而且將他們打包,在webpack4中,咱們用了功能更爲強大的url-loader去代替了file-loader(url-loader中內置了file-loader的功能),而且咱們配置了一系列的options,下面就挨個來解釋這些配置項的用途。
limit是對於圖片大小的判斷,低於咱們給定的數就會被轉換成base64的格式,單位是字節。
output則是圖片打包後的保存路徑,name是文件打包後的名字,在這裏我用了[hash],這會使文件打包事後的名字是一串哈希值
配置完成以後咱們來試驗一番吧。
首先咱們先在src文件夾中建立一個img用來放置待打包的圖片,而後在css中去引用這些圖片,
而後運行看看是否正常打包
代碼以下
layer.css
.test1{ width: 100px; height: 100px; background: blue; } .test2{ width: 100px; height: 100px; background-image: url(../img/1.jpg); }
咱們發如今dist目錄下生成了一個新的asset目錄,裏面就是咱們打包的圖片,而layer.html也能看到打包正常,可是圖片確沒有正常被引用,以下圖所示
彷佛圖片的路徑出了點問題,這是由於圖片是靜態資源,加載靜態資源咱們須要在output中配置一個名爲publicPath的參數來正確的加載路徑
具體代碼以下
output:{ filename:'layer.js', //輸出的文件名 publicPath:'./dist/', path : __dirname + '/dist' //輸出文件路徑 }
在配置完publicPath以後,咱們再次執行打包命令,而後看看layer.html,效果如圖
圖片的加載路徑正確了,背景圖也展示出來了。說明咱們的配置是正確的
彷佛忘了什麼?如今樣式文件不光有css,還有less和sass,這兩個文件的打包也是須要loader的,因此咱們來配置這兩個文件的打包吧
老規矩,先安裝loader
npm install less sass less-loader sass-loader --save-dev
配置能夠和cssloader的配置同樣,不過咱們須要注意一下須要修改一下識別的文件,分別是sass和less,具體配置以下
{ test: /.less$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } }, {loader:'less-loader'} ] },/*解析less, 把less解析成瀏覽器能夠識別的css語言*/ { test: /.sass$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } }, {loader:'sass-loader'} ] }/*解析sass, 把sass解析成瀏覽器能夠識別的css語言*/
配置完這個以後咱們也能夠打包less和sass文件了
有些時候咱們須要在html文件中引入html文件,這種狀況下咱們就須要導入html-loader
npm install html-loader --save-dev
配置以下
{ test: /.html$/, use: [ {loader:'html-loader'} ] }
配置完了咱們就能夠打包html文件了
最終webpack.config.js的代碼以下
module.exports = { entry:'./src/js/index.js',//入口文件 output:{ filename:'layer.js', //輸出的文件名 publicPath:'./dist/', path : __dirname + '/dist' //輸出文件路徑 }, module:{ rules:[ { test:/.js$/, use:[ {loader:'babel-loader'} ] }, { test: /.css$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } } ] },/*解析css, 並把css添加到html的style標籤裏*/ { test: /.(jpg|png|gif|svg)$/, use: [ { loader:'url-loader', options:{ limit: 500,//圖片小於500的話就把圖片轉爲base64格式 outputPath: 'assets/images/', name: '[hash].[ext]', } } ] }, { test: /.less$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } }, {loader:'less-loader'} ] },/*解析less, 把less解析成瀏覽器能夠識別的css語言*/ { test: /.sass$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } }, {loader:'sass-loader'} ] },/*解析sass, 把sass解析成瀏覽器能夠識別的css語言*/ { test: /.html$/, use: [ {loader:'html-loader'} ] } ] }, }
上面講的是打包一個js文件的狀況,在實際的開發應用中咱們的js文件顯然不止一個,這時候咱們須要多個入口文件來執行打包,有如下兩種方式可供你們選擇
1、以一個數組的方式來做爲文件的入口
代碼以下
entry:['./src/js/index.js','./src/js/index2.js'],//入口文件 output:{ filename:'layer.js', //輸出的文件名 publicPath:'./dist/', path : __dirname + '/dist' //輸出文件路徑 },
這時候index.js和index2.js會被一塊兒打包到layer.js中,咱們在index2.js中打印一個123,打包以後查看layer.js,發現打包事後的文件已經打包完成了這兩個文件,如圖所示
2、以一個對象做爲入口的文件
代碼以下
entry:{ a:'./src/js/index.js', b:'./src/js/index2.js' },//入口文件 output:{ filename:'layer.js', //輸出的文件名 publicPath:'./dist/', path : __dirname + '/dist' //輸出文件路徑 },
這個時間咱們執行打包,發現咱們只能打包其中一個js,另外一個js並不能被打包進來,
以下圖所示
咱們只有一個chunk值,官網也說這種狀況下,咱們在output這個出口文件下也須要從新配置一下,咱們的filename再也不是一個固定的文件名了,而應該是 '[name].js',這樣咱們打包的時候,就會自動根據對象的屬性名生成對應的文件,有幾個對象就會生成幾個打包對象,那麼就讓咱們打包一下看看吧。
這是咱們的打包結果,看來是打包成功了,而且生成了a和b兩個js文件
咱們在layer.html中引入這兩個js,發現和以前的layer.js是同樣的效果。
你覺得這樣就完結了嗎,並無,以前咱們打包完成以後仍是須要手動去引入打包事後的js,這種方法無疑是極爲很差的,webpack爲咱們提供了一個插件,來解決這個問題。
首先咱們須要安裝這個插件
npm install html-loader html-webpack-plugin --save-dev
安裝好了以後,咱們在webpack.config中去引用這個插件
const htmlWebpackPlugin = require('html-webpack-plugin');
而且在module.exports中新增一個plugins配置項
plugins:[ new htmlWebpackPlugin({ template:'layer.html', filename:'layer.html', }) ]
這時候咱們執行打包操做,運行結果以下
咱們打包了圖片,兩個js文件和layer.html這個文件,而後咱們發現dist目錄下也多了一個layer.html,這個html自動引入了咱們打包完成以後的js
代表咱們打包成功,之後也不須要擔憂去手動引用打包以後的js的問題了。
接下來咱們關注一下公共模塊的打包,在實際項目中,咱們是有不少個js文件的,這些js文件或多或少有一些公共的模塊,webpack能夠將其分離出來
首先咱們須要在項目中再次安裝一次webpack,由於咱們須要使用webpack的一些插件
在webpack4以前的版本中,打包公共模塊是用以下的方式
var CommonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin('common'); //把公共模塊提取出來, 並取名爲'common'(名字自起), webpack以後再out文件夾下生成common.js, 測試時記得引入提取出來的公共模塊js文件
而後在plugins配置中增長一個CommonsChunkPlugin 值就能夠了。
可是在webpack4,這種方法已經不能使用了,webpack給咱們提供了一種新的方式去提取公共文件使用spiltchunk來代替commonschunkplugin
具體配置以下
新增一個optimization配置項,和plugins同級,
optimization: { runtimeChunk: { name: "manifest" }, splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: "vendor", chunks: "all" } } } },
執行打包
打包成功,咱們發現dist文件夾下面多了一個manifest.js,這個js中放的就是a和b的公共模塊
接下來咱們來使用webpack服務器,
首先在項目目錄中安裝
npm install webpack-dev-server
在webapck4中,咱們能夠經過一個devServer的配置項來修改webpack服務器的內容
devServer: { contentBase: path.join(__dirname, "src/dist"), host: 'localhost', port:8496, compress: true//是否壓縮 },
host和port共同組成了咱們的網絡路徑,port是端口號,這個端口號是能夠修改的,而後咱們須要引入一個新的插件path
const path = require('path');
咱們經過path的join方法來肯定路徑,同時咱們能夠修改一下output的path,使其變爲
path : path.resolve(__dirname , '/dist') //輸出文件路徑
而後咱們執行
webpack-dev-server --mode development
(可能須要在項目中從新安裝一次webpack-cli)
運行結果以下圖所示
三行信息代表咱們的路徑
編譯成功,項目已經成功發佈到8496的端口去了
咱們可使用^C來終止該命令
webpack還有一些其餘的插件命令可使用,如
webpack.optimize.UglifyJsPlugin({minimize: true});//代碼壓縮//只支持es5 require("extract-text-webpack-plugin"); //將css獨立引入變成link標籤形式, 使用該插件須要獨立下載'npm install extract-text-webpack-plugin --save-dev', 同時下面的rules也必須更改
這裏就不一一贅述了
最後附上個人webpack.config.js的配置
const htmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path'); module.exports = { entry:{ a:'./src/js/index.js', b:'./src/js/index2.js' },//入口文件 output:{ filename:'[name].js', //輸出的文件名 publicPath:'./dist/', path : path.resolve(__dirname , '/dist') //輸出文件路徑 }, devServer: { contentBase: path.join(__dirname, "src/dist"), host: 'localhost', port:8496, compress: true }, module:{ rules:[ { test:/.js$/, use:[ {loader:'babel-loader'} ] }, { test: /.css$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } } ] },/*解析css, 並把css添加到html的style標籤裏*/ { test: /.(jpg|png|gif|svg)$/, use: [ { loader:'url-loader', options:{ limit: 500,//圖片小於500的話就把圖片轉爲base64格式 outputPath: 'assets/images/', name: '[hash].[ext]', } } ] }, { test: /.less$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } }, {loader:'less-loader'} ] },/*解析less, 把less解析成瀏覽器能夠識別的css語言*/ { test: /.sass$/, use: [ {loader:'style-loader'}, {loader:'css-loader', options: { importLoaders: 1 } }, {loader:'postcss-loader', options:{// 若是沒有options這個選項將會報錯 No PostCSS Config found plugins:(loader) => [ require('autoprefixer')( {broswers:['last 5 versions']} ), //CSS瀏覽器兼容 ] } }, {loader:'sass-loader'} ] },/*解析sass, 把sass解析成瀏覽器能夠識別的css語言*/ { test: /.html$/, use: [ {loader:'html-loader'} ] } ] }, optimization: { runtimeChunk: { name: "manifest" }, splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: "vendor", chunks: "all" } } } }, plugins:[ new htmlWebpackPlugin({ template:'layer.html', filename:'layer.html', }) ] }