Webpack2 提取共同的 css 文件的最佳實踐?以及 Webpack 的適用場景有哪些?

比如我有兩個 js 文件 hello.js 和 world.js,二者均引入了 base.css,具體內容如下所示:

如何才能做到讓 Webpack 打包時自動提取出 base.css 呢?我們知道,Webpack 可以藉助 CommonsChunkPlugin 自動提取出共有的 js 文件,但是 css 文件貌似不行。

首先聲明一下,目前我使用 Webpack2 + React,其他技術棧如果沒有這個問題,就當拋磚引玉了。以下是我的 Webpack.config,僅供參考:

除此疑問外,大家也可提出其他意見和建議,比如這個模塊配置不對,那個插件使用不當等等。

我的目標是前端打包流程的完全自動化,目前我的解決方案有兩種,分別如下所示:

1. HTML 模板中引入 base.css,Webpack 打包之後使用 NPM Scripts 把 base.css 從 /src/css 複製到 /dest/css。此種方法的弊端在於文件名永遠都是 base.css,無法解決緩存問題。至多使得 NPM Scripts 自動生成帶有 hash 值的文件名。但是生成的 HTML 文件中的 css 文件名還是需要手動替換,無法完全自動化。

2. 在 SegmentFault 上看到一個網友的做法:建立一個通用的 base-style.js,這個 js 文件什麼都不做,就是 import base.css。這個想法很巧妙,但是我在實際試驗之後發現也有一些細節問題,在此不再贅述。

我之所以要提問,是因為查到的資料不能完美解決現有問題。一般來說,我們所遇到的問題前人已經遇到過了,所以這很可能是一個危險的信號。因為這通常意味著沒有人有這樣的疑問,你有可能走錯路了,或者說這個東西你很可能還沒有完全入門。以下是我的疑問,敬請大家解惑:

1. 我的理解沒問題,但是沒有找到相關答案是因為我搜索的關鍵字不對(歡迎給出任何線索)

2. 我的理解沒問題,需求也合理,但是應該使用 Grunt 之類的 Task Runner(好吧,雖然我明白 Webpack 只是一個 Bundler,但是我在想能不能利用現有的 Webpack Plugins 和 NPM Scripts 來完成所有的任務運行,而不是額外再引入一個 Package)

3. 我的需求有問題,本來就是用來打包的,根本用不著單獨提取出來(如果是這樣,有關於前端工程化的一些思考也歡迎進一步指教)

4. 我應該自己寫一個插件來實現這個功能(呃......)

如果大家有任何線索,不局限於形式,比如文章、書籍、最佳實踐,甚至是一個想法等,歡迎不吝賜教。

-------- 更新 --------

經知友建議,在問題評論中添加了示意代碼的 Repo,託管在 GitHub 上,有興趣的同學可以 Pull 下來一觀。

經過這幾天的使用及反思,我不禁更想知道:Webpack 的適用場景是什麼,使用邊界在哪?任何前端開發都適用嗎?一個複雜的網頁應用顯然是適用的,但是不涉及到大量數據更新的頁面也適用嗎?比如一個簡單的靜態博客有必要使用嗎,似乎也沒有必要。


跑了下題主的項目代碼(見評論),發現問題出在 `CommonsChunkPlugin` 的 `minChunks` 配置上。

entry: {
react: ["react", "react-dom"]
}
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "react",
minChunks: Infinity
})
]

這樣的結果是只有 react 和 react-dom 被打包到公共文件,其他的公共文件都不會打包。

建議去掉 minChunks,使用默認配置就好了。

如果希望公共 js 文件裡面只有 React,但是 css 代碼能打包到公共 css,可以這樣寫:

minChunks: function (module, count) {
const resource = module.resource
// 以 .css 結尾的資源,重複 require 大於 1 次
return resource /.css$/.test(resource) count &> 1
}


ExtractTextWebpackPlugin

1. multi instance
2. 後綴名區分共有模塊,類似於匹配 xxx_.css 和 xxx.css 一個作為共有的loader,然後extract 一個instance 另一個保持原狀


我們大部分是多頁應用,現在的做法就是新建一個common.js作為入口,專門用來import基礎樣式和polyfill。配合extract插件就能生成一個公有的js和css,然後把地址掛載到html上。感覺和題主提到的第二種方法很像,不知道有什麼缺陷?


請問現在有合適的解決方法了嗎?


打包的話最好的方法還是通過js文件引入css吧。。

不知道題主遇到過什麼樣的細節問題,不過我也提一下想到的另一種方法吧

將css文件儲存在api端,前端通過ajax獲得css文件並引入到html中去

這樣相當於把各類問題都通過api端進行處理,前端負責動態引入

缺點就是想想就好麻煩。。還得再建一server。。


想問問這是一個單頁應用還是多頁應用?如果是單頁,就把公共樣式放到入口文件,如果是多頁,也沒必要提取公共css對吧


推薦閱讀:

php7 更新後對於 python 會造成怎樣的衝擊?python+c 擴展能否 hold 住性能?
前端工程師需要對 Linux 掌握到什麼程度?
作為一名前端開發人員,有哪些值得一讀的js代碼?
Python 能取代 PHP 的 Web 開發地位嗎?
CSS如何實現這種背景效果?

TAG:Web開發 | 前端開發 | 前端工程化 | React | webpack |