webpack的配置和安裝(2)

上一篇文章講述瞭如何安裝和配置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

clipboard.png
打包成功,而後咱們發如今根目錄下出現了一個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);

打包以後,運行效果如圖所示

clipboard.png
代表咱們的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也能看到打包正常,可是圖片確沒有正常被引用,以下圖所示
clipboard.png

彷佛圖片的路徑出了點問題,這是由於圖片是靜態資源,加載靜態資源咱們須要在output中配置一個名爲publicPath的參數來正確的加載路徑
具體代碼以下

output:{
        filename:'layer.js',    //輸出的文件名
        publicPath:'./dist/',
        path : __dirname + '/dist'    //輸出文件路徑
    }

在配置完publicPath以後,咱們再次執行打包命令,而後看看layer.html,效果如圖

clipboard.png

圖片的加載路徑正確了,背景圖也展示出來了。說明咱們的配置是正確的

彷佛忘了什麼?如今樣式文件不光有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,發現打包事後的文件已經打包完成了這兩個文件,如圖所示

clipboard.png

2、以一個對象做爲入口的文件
代碼以下

entry:{
        a:'./src/js/index.js',
        b:'./src/js/index2.js'
        },//入口文件
    output:{
        filename:'layer.js',    //輸出的文件名
        publicPath:'./dist/',
        path : __dirname + '/dist'    //輸出文件路徑
    },

這個時間咱們執行打包,發現咱們只能打包其中一個js,另外一個js並不能被打包進來,
以下圖所示

clipboard.png
咱們只有一個chunk值,官網也說這種狀況下,咱們在output這個出口文件下也須要從新配置一下,咱們的filename再也不是一個固定的文件名了,而應該是 '[name].js',這樣咱們打包的時候,就會自動根據對象的屬性名生成對應的文件,有幾個對象就會生成幾個打包對象,那麼就讓咱們打包一下看看吧。

這是咱們的打包結果,看來是打包成功了,而且生成了a和b兩個js文件clipboard.png
咱們在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',
            })
        ]

這時候咱們執行打包操做,運行結果以下

clipboard.png
咱們打包了圖片,兩個js文件和layer.html這個文件,而後咱們發現dist目錄下也多了一個layer.html,這個html自動引入了咱們打包完成以後的js

clipboard.png
代表咱們打包成功,之後也不須要擔憂去手動引用打包以後的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"
                    }
                }
            }
        },

執行打包

clipboard.png
打包成功,咱們發現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)
運行結果以下圖所示

clipboard.png

三行信息代表咱們的路徑
編譯成功,項目已經成功發佈到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',
            })
        ]
}
相關文章
相關標籤/搜索