webpack

webpack(v3.*)javascript

一、webpack介紹css

webpack官網:https://webpack.js.org/
webpack中文官網:https://doc.webpack-china.org...
webpack打包工具源代碼:https://github.com/webpack/we...html

二、初始化項目vue

cd yourproject
npm init       //生成package.json文件
npm install webpack --save-dev

三、webpack.config.js配置文件html5

(1)、context:上下文,這裏省略了,默認爲當前文件模塊的絕對路徑,下面的entry和output中的路徑都是相對於context上下文的相對路徑.java

(2)、output屬性:(v3.10.0版本要求path是絕對路徑,須要使用node.js的path模塊)node

注意: path.resolve方法用於將相對路徑轉爲絕對路徑。react

var path = require("path");  //使用前引入path模塊
module.exports = {
    entry: './src/js/main.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist/js'),
        publicPath: "https://cdn.example.com/"  //用publicPath配置打包後生成線上地址
    }
}

注意: publicPath,當咱們須要上線的時候設置此屬性,最後打包的文件路徑會被替換爲publicPath設置的地址值。webpack

注意: filename: '[name]-[chunkhash].js',filename使用佔位符確保每一個文件具備惟一的名稱。同時使用chunkhash能夠達到控制文件版本號的做用,這點與gulp是相通的原理。因此,一旦文件作了修改,再執行webpack,則更改過的文件的chunkhash會發生改變,未作改動的文件的chunkhash不變。git

(3)、plugins屬性

介紹:plugins 是一個數組,裏面是實例化的plugin,即new HtmlWepackPlugin({//code}),這種形式。

① html-webpack-plugin插件:該插件用於生成一個HTML5文件,這個文件用script標籤引用全部webpack包。(https://www.npmjs.com,npm官網...

//安裝
npm install html-webpack-plugin --save-dev

//webpack.config.js配置文件中引入
var HtmlWepackPlugin = require("html-webpack-plugin");

//設置配置項
plugins: [
    new HtmlWepackPlugin({
        filename:'index-[hash].html',  //輸出文件名稱
        template:'index.html',   //模板路徑
        inject:"head",     //值:body,head,false;script和link文件注入body或head中,或者false不注入。
        chunks:["index","common"],      //容許插入到模板中的一些chunk,不配置此項默認會將entry中全部的chunk注入到模板中。多頁應用配置多個頁面時,每一個頁面注入的thunk應該是不相同的,須要經過該配置爲不一樣頁面注入不一樣的thunk.
        excludeChunks: ["constan"],     //這個與chunks配置項正好相反,用來配置不容許注入的thunk。
        showErrors: true,     //值:true/false,默認true;是否將錯誤信息輸出到html頁面中。這個頗有用,在生成html文件的過程當中有錯誤信息,輸出到頁面就能看到錯誤相關信息便於調試。
        title:"MyApp",   //須要在引用template模板中調用此變量
        minify: {  //壓縮代碼
            collapseWhitespace: true,   //刪除空格
            html5: true
        }
    })
]

注意: title屬性的坑:var HtmlWebpackPlugin = require('html-webpack-plugin'); 這個變量隨意。可是在模板中<title><%= htmlWebpackPlugin.options.title %></title>必須使用駝峯式命令。否則會報錯一直提示這個插件未定義。

注意: 在頁面中引入inline的script方法以下:

在github上,https://github.com/jantimon/h...。共用的main.js以inline的形式引進,a.js,b.js,c.js之外鏈的形式引進.模板index.html中,

首先在<head>中

<script type="text/javascript">
        <%= compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %>
    </script>

重點:!!!compilation.assets是webpack暴露出來能夠獲取文件數據的方法。經過傳文件名路徑進這個對象,拿到這個文件的索引,經過調用source拿到文件內容。
compilation.assets須要的是不帶publicPath,htmlWebpackPlugin.files.chunks.main.entry帶publicPatch,因此用substr()截取。

而後在<body>中:

<%= htmlWebpackPlugin.files.chunks[k].entry %>

最後在webpack.config.js中: inject屬性設置爲false便可。

(4)、loader屬性(以babel-loader爲例,用babel-loader將js文件轉義爲瀏覽器可識別的js)

module:{         
    rules:[    //模塊規則
        {
            test: /\.js$/,    //正則匹配
            use: [{   
                loader:'babel-loader',
                options:{
                    presets: ["env"] //採用babel-loader的"env"規則將找的es6,es7,es5語法轉碼爲瀏覽器可識別的js
                }
            }],
            include: [
             path.resolve(__dirname, "/src")   //指定babel-loaders尋找的文件路徑,注意需是絕對路徑
            ],
            exclude: [
             path.resolve(__dirname, "/node_modules/")   //排除node_modules文件下js,注意需是絕對路徑
            ]
        }
    ]
},

注意: webpack官網介紹到:「Rule.loader is a shortcut to Rule.use: [ { loader } ]」. 即下圖:

圖片描述

(5)、loader屬性(css處理的loader)(postcss參考文章:https://segmentfault.com/a/11...

在web開發中瀏覽器兼容問題,咱們不得不使用兼容性前綴,less語言在編譯時能夠補全css代碼的兼容性前綴,可是針對css文件不全前綴須要使用postcss-loader。以下圖:

圖片描述

在common.css中引入其餘的css文件:
圖片描述

在app.js入口文件中引入common.css,這樣打包的時候就能將css文件進行打包:
圖片描述

(6)、wbpack-dev-server

//首先安裝插件
npm i webpack-dev-server  --save-dev
npm i cross-env  --save-dev
npm i html-webpack-plugin  --save-dev

package.json文件:

"scripts":{
    //prod環境
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    //dev環境
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js"
  }

webpack.config.js文件:

const path = require("path")  
const HTMLWebapckPlugin = require("html-webpack-plugin")
const webpack = require('webpack')  //引入webpack 

//在package.json中的「NODE_ENV=development」,可經過下面的process.env讀到變量NODE_ENV
const isDev = process.env.NODE_ENV === "development"


const config = {

    target:"web",//web平臺

    entry: path.join(__dirname,'src/index.js'),
    output:{
        filename:'bundle.js',
        path:path.join(__dirname,"dist")

    },
    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:'vue-loader'
            },
            {
                test:/\.css$/,
                use:[
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test:/\.(gif|jpg|jpeg|png|svg)$/,
                use:[
                    {
                        loader:'url-loader',
                        options:{
                            limit:1024,
                            name:'[name]-[hash].[ext]'
                        }
                    }
                ]
            }
        ]
    },
    plugins:[
        //使用Vue、react框架時須要DefinePlugin這的插件,由於框架會根據不一樣環境打包依賴,因此要區分環境從而選擇不一樣的依賴
        new webpack.DefinePlugin({
            //定義環境變量,對應上面的isDev判斷
            'process.env':{
                NODE_ENV:isDev ? '"development"' : '"production"' //注意此處單引號內還須要雙引號
            }
        }),
        //生成HTML頁面
        new HTMLWebapckPlugin()
    ]
}

//dev環境
if(isDev){
    //經過devtool對代碼進行映射,能夠在瀏覽器端能夠調試
    config.devtool = "#cheap-module-eval-sourve-map"
    //devserver 是在webpack2之後纔出現的
    config.devServer = {
        port:'8020', //端口號
        host:"0.0.0.0", //設置成這樣後,移動端也能夠通IP訪問頁面
        //webpack編譯時任何錯誤顯示在瀏覽器中
        overlay:{
            errors:true,
        },
        open:true,//自動打開瀏覽器
        hot:true //webpack功能:再也不從新刷新整個頁面,而是局部更新,即熱更新
    }
    config.plugins.push(
        new webpack.HotModuleReplacementPlugin(),  //搭配hot:true一塊兒使用
        new webpack.NoEmitOnErrorsPlugin()  //搭配hot:true一塊兒使用,去除一些不須要展現的信息
    )
}


module.exports = config

執行npm run dev 就能夠經過localhost:8020打開頁面

(7)、webpack單獨打包css文件

//安裝依賴
npm i extract-text-webpack-plugin

在webpack.config.js文件中引用:(結合6中的配置文件)

//dev環境
if(isDev){
    config.module.rules.push(
        {
            test:/\.scss$/,
            use:[
                'style-loader',
                'css-loader',
                {
                    loader:'postcss-loader',
                    options:{
                        sourceMap:true
                    }
                },
                'sass-loader'

            ]
        }
    )
    config.devtool = "#cheap-module-eval-sourve-map"
    //devserver 是在webpack2之後纔出現的
    config.devServer = {
        port:'8020', //端口號
        host:"0.0.0.0", //設置成這樣後,移動端也能夠通IP訪問頁面
        //webpack編譯時任何錯誤顯示在瀏覽器中
        overlay:{
            errors:true,
        },
        open:true,//自動打開瀏覽器
        hot:true //熱更新
    }
    config.plugins.push(
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin()
    )
}else{
//正式環境
    config.output.filename='[name].[chunkhash:8].js'  //正式環境使用chunkhash,dev環境不能使用chunkhash,可以使用hash.
    config.module.rules.push({
        test:/\.scss$/,
        use:ExtractTextWebpack.extract({
            fallback:'style-loader',
            use:[
                'css-loader',
                {
                    loader:'postcss-loader',
                    options:{
                        sourceMap:true
                    }
                },
                'sass-loader'
            ]
        })
    })
    config.plugins.push(
        new ExtractTextWebpack('style.[contentHash:8].css')
    )
}
注意:vue組件中的css樣式是不會打包到上面的style.[contentHash:8].css文件中的,由於他是異步加載的。

(8)、單獨打包類庫文件及hash

將類庫代碼和業務代碼分離打包,利用瀏覽器長期的緩存類庫代碼。
//正式環境配置
 {
    config.entry = {
    //業務邏輯代碼
   app:path.join(__dirname,"src/index.js"),
   //類庫代碼在此聲明,此處以Vue框架爲例
    vendor: ['vue']
    }
    config.output.filename='[name].[chunkhash:8].js',
    config.module.rules.push({
    test:/\.scss$/,
    use:ExtractTextWebpack.extract({
    fallback:'style-loader',
    use:[
        'css-loader',
        {
            loader:'postcss-loader',
            options:{
                sourceMap:true
            }
        },
        'sass-loader'
    ]
    })
    }),
    config.plugins.push(
    new ExtractTextWebpack('style.[contentHash:8].css'),
    //單獨打包,app中就不會出現類庫代碼,必須放在runtime以前
    new webpack.optimize.CommonsChunkPlugin({
    //name屬性值要和上面定義的vendor一致
    name:'vendor'
    }),
    new webpack.optimize.commonsChunkPlugin({
    name:'runtime'
    })
    )
 }
hash與chunkhash區別:
hash:打包的全部文件共用的一個值
chunkhash:打包的不一樣的塊擁有不一樣的chunkhash,因此正式環境應使用chunkhash,這樣能夠保證類庫文件不會再每次更改業務從新打包後,又擁有一個新的hash值,而是一直使用以前的chunkhash,這樣瀏覽器就不會在去下載那些依賴,從而實現了緩存。

詳細請見:https://www.imooc.com/article/21538
相關文章
相關標籤/搜索