webpack總結(jié) & 個(gè)人理解

目錄:

  1. 學(xué)習(xí)資源
  2. 概念總結(jié)
  3. webpack必要元素
  4. webpack其他元素
  5. 遇到的問(wèn)題
  6. 常見(jiàn)loader整理
  7. 常見(jiàn)plugin整理
  8. devServer擴(kuò)展閱讀

1. 學(xué)習(xí)資源

maximilian 教學(xué)視頻
webpack2 中文文檔

2. 概念性總結(jié)

學(xué)習(xí)總結(jié)

由于個(gè)人對(duì)于抽象概念的理解能力較差,剛開(kāi)始閱讀文檔進(jìn)度很慢,而且看下來(lái)的效果并不好;
通過(guò)觀看教學(xué)視頻,感覺(jué)才是真正的體會(huì)到了webpack的實(shí)際用途,從實(shí)際用途出發(fā)再去理解文檔就顯得輕松一些;
雖然筆記寫(xiě)了一大篇,實(shí)際運(yùn)用還是有不少坑,零碎的知識(shí)點(diǎn)也不少... 繼續(xù)實(shí)踐繼續(xù)總結(jié)....

一句話總結(jié)時(shí)間:

將entry文件涉及到的所有js、css、less、img等(一條引用鏈),打包為一個(gè)獨(dú)立js,能夠替代以上所有的文件。

如何形成一條完整引用鏈:

原本的css在html中使用link標(biāo)簽引用;現(xiàn)改為在js中import './xxx.css'
如果多個(gè)css之間關(guān)聯(lián)使用(如scss),可以在css內(nèi)部形成一條引用鏈,即在css中 import './xxx.css',再在js中引用這個(gè)處在css引用鏈末端的css

bundle.js的用處:

生成的bundle.js可以替代entry中對(duì)應(yīng)源的所有涉及文件資源;
實(shí)際表現(xiàn)為,原先所有的html中的引用(link與script標(biāo)簽),都可以用引入bundle.js來(lái)替代

打包命令:

webpack 根據(jù)webpack.config.js生成打包文件
webpack -p 根據(jù)webpack.config.js生成打包文件,并且把打包文件壓縮
webpack-dev-server 在服務(wù)器上運(yùn)行webpack打包后的項(xiàng)目,打包文件只出現(xiàn)在服務(wù)器上,不出現(xiàn)在項(xiàng)目實(shí)體中

3. 必要要素:

  • entry
  • output
  • loader
  • plugins [array]
// 基本模板
var path = require("path");     // 路徑解析package

// require獲取、配置第三方插件
var extractTextPlugin = require("extract-text-webpack-plugin"); 
var extractPlugin = new extractTextPlugin({
    filename:'main.css'
});
var htmlWebpackPlugin = require('html-webpack-plugin');
var cleanPlugin = require('clean-webpack-plugin');

// 引入webpack-package,使用其中的插件
var webpack = require('webpack');    

// 以module的形式輸出
module.exports = {

    entry: {
        bundle: './src/js/app.js'   // webpack的入口文件,將app中所有使用到的引用以及語(yǔ)法特性等能夠打包的內(nèi)容全部打包;  
    },

    output: {
        path: path.resolve(__dirname, "dist"),
        filename: 'bundle.js'  // entry文件的打包最終成果的文件名
        publicPath: '/dist'    // 此屬性用于在webpack-dev-server部署到服務(wù)器時(shí)候,告訴服務(wù)器該去哪里查找(查找webpack生成在服務(wù)器端的打包文件)
    },

    module: {
        //  rules以數(shù)組屬性,配置不同文件的打包規(guī)則
        rules: [
            {
                test: /\.js$/,   // 匹配原則,正則表達(dá)式:以.js結(jié)尾
                // 當(dāng)use中出現(xiàn)多個(gè)loader,加載順序從后往前,比如打包c(diǎn)ss文件時(shí),寫(xiě)作:['style-loader','css-loader'],先用css-loader載入css文件,再使用style-loader把樣式style引入待打包的js文件
                use: [
                    {
                        loader: 'babel-loader',
                        // option類似于一個(gè)get路徑中的queryString,用于配置loader,可以寫(xiě)作字符串形式
                        options: {
                            presets: ['es2015']
                        }
                    }
                ]
            } 
        ]
    },

    plugins: [
        // extractPlugin 指定inject位置
        extractPlugin, 
        // DefinePlugin: 暴露全局變量
        new webpack.DefinePlugin({
          PRODUCTION: JSON.stringify("production")  
        })
        // ProvidePlugin:解析符號(hào)定義
        new webpack.ProvidePlugin({
           $: 'jquery',       // 告訴解析器,遇到這個(gè)符號(hào),就去找package
        }),
        // htmlWebpackPlugin插件: 用于復(fù)制html,并且向其中自動(dòng)注入(inject)服務(wù)器端生成的js等文件
        new htmlWebpackPlugin({
          filename: 'index.html',
          template: 'src/index.html'
        }),
        // cleanPlugin用于:每次使用webpack生成打包文件前先抹除dist文件下的舊打包文件
        new cleanPlugin(['dist'])   
    ]
}

4. 其他屬性

module.exports = {
    // devServer: 用于配置webpack-dev-server命令啟動(dòng)的服務(wù)器
    devServer: {
        // publicPath: 此路徑下的打包文件在瀏覽器中可訪問(wèn);也是打包文件的存放目錄,必須保證"/"開(kāi)頭、結(jié)尾
        publicPath: /asset/   // 確定應(yīng)該從哪里提取bundle,優(yōu)先于contentBase屬性
        contentBase: path.join(__dirname, "dist"),   // 告訴服務(wù)器從哪里提供(靜態(tài))內(nèi)容
        compress: true,   // 一切服務(wù)都啟用gzip壓縮
        port: 9000       //  指定監(jiān)聽(tīng)請(qǐng)求的端口號(hào)
        headers: {"X-Custom-Foo": "bar"}   // 在所有請(qǐng)求中添加首部?jī)?nèi)容
        historyApiFallback: true   // 任意404相應(yīng)提供為index.html 
        host: "0.0.0.0"  // 指定使用一個(gè)host  默認(rèn)是localhost
        hot: true    // 熱加載
        lazy: true  // 惰性模式:只在請(qǐng)求時(shí),才編譯bundle(不watch文件變動(dòng)) 
        proxy: {
            "/api": "http://localhost:3000",  // 向后端服務(wù)器3030發(fā)送api請(qǐng)求
            // 對(duì)當(dāng)前服務(wù)器/api/users的請(qǐng)求,現(xiàn)在會(huì)被代理到http://localhost:3000/api/users
            pathRewrite: {"^/api" : ""},   // 重寫(xiě)路徑:可以停止傳遞
            secure: false,    // 默認(rèn)不接受https上的使用無(wú)效證書(shū)的后端服務(wù)器;set false則接受所有
            bypass: function(){}   // 對(duì)路由進(jìn)行處理,在不停用代理的情況下繞過(guò)代理
        }

    watch: true,   // watch屬性監(jiān)測(cè)文件改動(dòng),默認(rèn)false

    devtool: 'source-map',   // 當(dāng)js使用了uglify插件進(jìn)行壓縮,debug時(shí)無(wú)法一一對(duì)應(yīng),因此使用source-map建立映射


}

5. 遇到的問(wèn)題

1、 圖片打包路徑引用問(wèn)題

引用webpack打包的圖片,引用路徑錯(cuò)誤
錯(cuò)誤原因: 對(duì)于原始圖片,使用了相對(duì)路徑進(jìn)行引用

解決方法1:

源碼圖片路徑和打包后的圖片路徑保持一致,比如:源碼圖片是放在/src/img/a.png下,引用圖片的的css路徑是/src/style/a.css, 這時(shí)候a.css的引用寫(xiě)法是 url("../img/a.png");打包后的圖片路徑是放在/build/img/a.png,引用圖片的的css路徑是/build/style/a.css, 這時(shí)候a.css的引用寫(xiě)法還是 url("../img/a.png"),這時(shí)候就不會(huì)出問(wèn)題

解決方法2:

webpack.config.js使用絕對(duì)路徑publicPath:
如果是放在dist目錄下:

output: {
        publicPath:'/dist/'
}

這樣所有資源文件的路徑都會(huì)把publicPath放到前面,就不會(huì)有路徑問(wèn)題了

6. loader整理

  • less-loader 引入less文件
  • css-loader 引入css文件
  • style-loader 引入樣式
  • bable-core 轉(zhuǎn)換es6
  • babel-loader 引入轉(zhuǎn)換后的js
  • html-loader 轉(zhuǎn)換html的import

7. 插件整理

  • html-webpack-plugin 重建html,包含webpack打包后的正確引用inject
  • clean-webpack-plugin 清除歷史build文件(dist)后再重新打包
  • extract-text-webpack-plugin 分離css文件
  • CommonsChunkPlugin 公共模塊提取單獨(dú)打包
  • uglifyjs-webpack-plugin 壓縮js文件

8. devServer配置擴(kuò)展閱讀

devServer: {
  // webpack-dev-server options

  contentBase: "/path/to/directory",
  // Can also be an array, or: contentBase: "http://localhost/",

  hot: true,
  // Enable special support for Hot Module Replacement
  // Page is no longer updated, but a "webpackHotUpdate" message is sent to the content
  // Use "webpack/hot/dev-server" as additional module in your entry point
  // Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does. 

  historyApiFallback: false,
  // Set this as true if you want to access dev server from arbitrary url.
  // This is handy if you are using a html5 router.

  compress: true,
  // Set this if you want to enable gzip compression for assets

  proxy: {
    "**": "http://localhost:9090"
  },
  // Set this if you want webpack-dev-server to delegate a single path to an arbitrary server.
  // Use "**" to proxy all paths to the specified server.
  // This is useful if you want to get rid of 'http://localhost:8080/' in script[src],
  // and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ).

  setup: function(app) {
    // Here you can access the Express app object and add your own custom middleware to it.
    // For example, to define custom handlers for some paths:
    // app.get('/some/path', function(req, res) {
    //   res.json({ custom: 'response' });
    // });
  },

  // pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server
  staticOptions: {
  },

  clientLogLevel: "info",
  // Control the console log messages shown in the browser when using inline mode. Can be `error`, `warning`, `info` or `none`.

  // webpack-dev-middleware options
  quiet: false,
  noInfo: false,
  lazy: true,
  filename: "bundle.js",
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000
  },
  // It's a required option.
  publicPath: "/assets/",
  headers: { "X-Custom-Header": "yes" },
  stats: { colors: true },

  https: {
    cert: fs.readFileSync("path-to-cert-file.pem"),
    key: fs.readFileSync("path-to-key-file.pem"),
    cacert: fs.readFileSync("path-to-cacert-file.pem")
  }
});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容