摘要:這里要介紹的是工作流中的一種很普遍的代碼加工流程正常的業務邏輯開發流程需要經過預處理器如或,然后再經過后處理器如進行深加工。
還未看的,可以點擊查看上兩篇文章喲:Webpack 最佳實踐總結(一)、Webpack 最佳實踐總結(二)
好了,這篇是第三篇,也是完結篇,我感覺這一篇是最亂的一篇,湊合著看吧,不會讓你失望的
整合 CSS 加工流有時候,前端項目中除了 JavaScript 外,還有一個更重要的 CSS 需要我們花點精力進去。這里主要陳述一下如何將 CSS 加工流整合到 webpack 中,因為 CSS Modules 的情況比較復雜,所有暫還未打算介紹更多關于 CSS Modules 的內容
CSS 工作流指什么?好的工作流可以提供開發效率,節約開發成本。這里要介紹的是 CSS 工作流中的一種很普遍的代碼加工流程:正常的 CSS 業務邏輯開發流程需要經過 CSS 預處理器(如 Sass 或 Less),然后再經過后處理器(如 PostCSS)進行深加工。Sass 和 less 讓我們吃上"語法糖"去快捷編寫 CSS,PostCSS 可以讓我們不再關心每條語句是否兼顧不同和不同版本的瀏覽器
在 webpack 上整合 CSS 加工流實現方式如下:
配置預處理器
這里以 Sass 作為預處理器,如下:
// webpack.config.js const webpack = require("webpack"); const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { module: { rules: [ // ... { test: /.scss$/, exclude: /node_modules/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [ { loader: "css-loader", options: { minimize: true } }, "postcss-loader", "sass-loader" ] }) } ] } }
配置后處理器
這里以 PostCSS 作為后處理器,如下:
// webpack.config.js const webpack = require("webpack"); const autoprefixer = require("autoprefixer"); module.exports = { plugins: [ new webpack.LoaderOptionsPlugin({ options: { postcss: [ autoprefixer({ browsers: [ "last 3 version", "ie >= 10" ] }) ], context: staticSourcePath } }) ] }
設置外聯
// webpack.config.js const ExtractTextPlugin = require("extract-text-webpack-plugin"); // 存放靜態資源,諸如圖片或者是 normalize.css const staticSourcePath = path.join(__dirname, "static"); module.exports = { // ... entry: { // 設置入口文件,順序是靜態資源 -> custom.scss -> 項目里其他 scss base: path.resolve(staticSourcePath, "src/public/custom.scss") }, // ... plugins: [ // 創建 標簽,并將 src 指向最終生成的 CSS 文件,需要 html-webpack-plugin new ExtractTextPlugin({ filename: "[name].[contenthash].css", allChunks: true }) ] }壓縮第三方庫
以 Moment.js 和 Lodash 為例
Moment.jsMoment.js(v2.18.1) 是一個用于日期的 JavaScript 庫,默認情況下,只有你安裝它到你的項目中,即使壓縮后,也會占據217kb大小。相對于在2017年8月1日的統計,對比與 JavaScript 的 446kb 的平均大小,這是實在是太大了。不過 webpack 可以去掉 Moment.js 其中無用的代碼。
其中有 165kb 的大小是用于本地化的語言包,即便你不去用它們,它們在默認的情況下也會被包含進來。如下代碼來自 moment 的 gitihub
// moment/src/lib/locale/locales.js function loadLocale(name) { var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node if (!locales[name] && (typeof module !== "undefined") && module && module.exports) { try { oldLocale = globalLocale._abbr; require("./locale/" + name); // because defineLocale currently also sets the global locale, we // want to undo that for lazy loaded locales getSetGlobalLocale(oldLocale); } catch (e) { } } return locales[name]; }
上面的代碼會使 Moment.js 在運行期間動態地選擇相應文件去加載。
要解決它需要用到 ContextReplacementPlugin,一款替換上下文的插件,例子如下:
// webpack.config.js const webpack = require("webpack"); module.exports = { plugins: [ new webpack.ContextReplacementPlugin( // 需要被處理的文件目錄位置 /moment[/]locale/, // 正則匹配需要被包括進來的文件 /(en|zh-cn).js/ ) ] };Lodash
Lodash 是一款方便開發 JavaScript 的工具集合,測試版本為4.17.4。
當你項目包含有 Lodash 的時候,你打包出來的文件至少增加 75kb,多出來的大小包含了 316 個 Lodash 的函數。如果你只是使用了其中少數,例如 20 個,那么大概有 65 kb 是多余的。下面將列出兩種去掉這些多余的代碼的方法:
方法1:
還記得 webpack最佳實踐(一) 提及的 Tree-shaking 嗎?正因為有它,我們可以利用這個特性非常容易做到按需引用,如下:
import _ from "lodash"; _.get();
修改為
import get from "lodash/get"; get();
代碼量從 72kb 壓縮到 8.27kb
方法2:
方法1只適合剛開始玩一個項目的時候,并不怎么適合玩開了的項目,除非重寫一次,這工作量太大了,另外一個原因是 lodash 的方法名會容易跟自定義的函數名沖突,造成隱藏性bug。方法2就是解決這兩個問題,那就是使用babel-plugin-lodash
babel-plugin-lodash 是一款通過 babel 去實現將 lodash 的import用法編譯為最佳實踐的插件,配置如下:
打開.babelrc,添加下面配置
{ "plugins": ["lodash"] }
更多的配置方式可以查看文檔,這里不再作太多介紹。更具體的優化效果看下面:
import _ from "lodash"; _.get({ a: { b: 5 } }, "a.b");
上面的代碼是沒有使用babel-plugin-lodash,使用之后,會被重新編譯為下面:
import _get from "lodash/get"; _get({ a: { b: 5 } }, "a.b");
跟方法1一樣,代碼量從 72kb 壓縮到 8.27kb
當然如果你想更進一步壓縮代碼,可以嘗試與lodash-webpack-plugin搭配,它會更深一步地去刪除一些lodash的方法里的代碼。例如_.get默認支持深路徑查詢,如果你不需要支持深路徑查詢,你可以開啟這個插件,這個方法就會被去掉這個支持:
只使用babel-plugin-lodash
import _ from "lodash"; _.get({ a: { b: 5 } }, "a.b"); // → returns 5
使用babel-plugin-lodash和lodash-webpack-plugin 之后
import _get from "lodash/get"; _get({ a: { b: 5 } }, "a.b"); // → returns undefined
代碼量從72kb 壓縮到 772b
啟用 scope hoistingscope hoisting 對于 webpack 來說,就是將以前的模塊引用鏈拍扁為一個但又不會影響到已有的代碼。更好理解scope hoisting推薦閱讀:here
目前只有 webpack v3 以上版本才支持scope hoisting,開啟它是需要手動配置,如下:
// webpack.config.js const webpack = require("webpack"); module.exports = { plugins: [ new webpack.optimize.ModuleConcatenationPlugin() ] };其他好用的插件
preload-webpack-plugin 讓靜態資源支持 DNS 預解析和預加載,配置如下:
// webpack.config.js const PreloadWebpackPlugin = require("preload-webpack-plugin"); module.exports = { // ... plugins: [ new PreloadWebpackPlugin({ rel: "preload", as: "script", include: "all", fileBlacklist: [/.(css|map)$/, /base?.+/] }) ] }
script-ext-html-webpack-plugin 讓 js 加載方式支持 Async 或 defer,配置如下:
// webpack.config.js const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin"); module.exports = { // ... plugins: [ new ScriptExtHtmlWebpackPlugin({ defaultAttribute: "defer" }) ] }總結
有點亂,不好總結,大概就是整合 CSS 代碼加工流程到 webpack 中、壓縮第三方庫(Moment.js 和 Lodash )、啟用scope hoisting和其他好用的插件
大概就這樣,內容較多~
文章首發于:https://www.linpx.com/p/webpa...
歡迎訪問我的博客:https://www.linpx.com
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84834.html
摘要:這里要介紹的是工作流中的一種很普遍的代碼加工流程正常的業務邏輯開發流程需要經過預處理器如或,然后再經過后處理器如進行深加工。 還未看的,可以點擊查看上兩篇文章喲:Webpack 最佳實踐總結(一)、Webpack 最佳實踐總結(二) 好了,這篇是第三篇,也是完結篇,我感覺這一篇是最亂的一篇,湊合著看吧,不會讓你失望的 整合 CSS 加工流 有時候,前端項目中除了 JavaScript ...
摘要:它會代替所有的實例的值為,從而使知道那些判斷表達式總是錯誤的,從而刪除相關代碼,進一步壓縮打包文件模塊機制項目中使用的,通過也能通過打包有用的代碼,進一步減少大小。 好久沒寫文章,這次預計會帶來3篇的 Webpack 系列文章,將會在這幾天內更新完。 Webpack3 自今年6月20日正式發布而來,給我們帶來Scope Hoisting和Magic Comments兩大功能,可惜不在這...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
摘要:默認做法是告訴瀏覽器這個文件的緩存時間,然后當文件內容被修改,則需要重命名該文件告訴瀏覽器需要重新下載和緩存,例如也能做類似的工作。 上一篇介紹了 Webpack 優化項目的四種技巧,分別是通過 UglifyJS 插件實現對 JavaScript 文件的壓縮,css-loader 提供的壓縮功能,配置NODE_ENV可以進一步去掉無用代碼,tree-shaking幫助找到更多無用代碼 ...
閱讀 2609·2021-11-18 10:02
閱讀 2278·2021-09-30 09:47
閱讀 1745·2021-09-27 14:01
閱讀 3109·2021-08-16 11:00
閱讀 3163·2019-08-30 11:06
閱讀 2391·2019-08-29 17:29
閱讀 1531·2019-08-29 13:19
閱讀 444·2019-08-26 13:54