css初始化样式文件_前端必备技能 webpack 4. webpack处理CSS资源
每篇文章純屬個人經驗觀點,如有錯誤疏漏歡迎指正
??因為?webpack?本身只具有識別?JS?的能力,所以涉及到其他資源,需要我們通過?loader?來進行特殊處理,針對不同的樣式資源,需要以下幾個?loader:
style-loader:
用于加載?css?文件,會通過??標簽將相應內容插入到頁面中;
css-loader:
用于處理?.css?文件,幫助?webpack?識別資源;
less-loader:
用于處理?.less?文件,將?.less?文件編譯成?.css?文件;
sass-loader:
用于處理?.sass/.scss?文件,將?.sass?文件編譯成?.css?文件;
postcss-loader:
通過?PostCSS?處理?.css/.sss?文件;
stylus-loader:
用于處理?Stylus?文件;
PostCSS 和 Stylus:
[1]?PostCSS?官網地址:https://www.postcss.com.cn/
[2]?Stylus?官網地址:https://stylus.bootcss.com/
這里推薦張鑫旭大大提供翻譯的?Stylus?中文文檔:
[3]?張鑫旭 ·?Stylus?中文版參考文檔之綜述:https://stylus.bootcss.com/
一、打包資源
??我們先創建項目并進行相應的初始化,同時創建一個簡單的?webpack?配置文件,對創建項目過程有疑問的同學,可以查看?前端必備技能 webpack - 2. webpack環境安裝?的第四部分。
// webpack.config.js// 引入 NodeJS 中的 Path 模塊暴露的 resolve 方法來處理路徑問題 // 同樣可以使用 join 方法const { resolve } = require('path');// 采用 CommonJS 語法暴露配置文件module.exports = { // 開發模式 mode: "development", // 入口文件 entry: "./src/index.js", // 打包出口 output: { // 設置打包文件名 filename: "[name]-[chunkhash:8].js", // 設置打包后的文件路徑 // __dirname 為 NodeJs 中的變量,代表當前文件的絕對目錄 path: resolve(__dirname, "dist") }, // loader 配置 module: { rules: [ // 詳細配置 ] }, plugins: []}??這里推薦先將需要的?loader?都裝好,將下列命令中的?loadername?替換為相應名稱即可:
npm?i?loadername?-D??準備工作完成后,我們來嘗試打包各種類型的樣式文件吧。
1.1 打包 .css 資源
??在?src?下新建一個?index.css?文件,簡單書寫一些樣式,并在入口文件?index.js?中將資源引入:
// index.jsimport?"./index.css";??對于普通的?css?資源,只需要引入?style-loader?和?css-loader?即可處理。所以沒安裝?loader?的需要先進行安裝:
npm?i?style-loader?css-loader?-D??接下來我們對?webpack.config.js?進行修改:
rules: [ { // 使用正則匹配所有 .css 結尾的文件 test: /\.css$/, // 注意 loader 的處理順序是從下到上,從右到左 // 需要特別注意, `loader` 在引入時對順序是有要求的!!! use: [ // style-loader 會通過 style 標簽將 JS 文件中的 css 資源添加到頁面中 "style-loader", // css-loader 會將 css 文件變成 CommonJS 的模塊資源,加載到 JS 文件中 "css-loader" ], }]??然后打包:
??打包完成后,我們可以手動創建一個?html?文件將生成的?js?文件引入,查看效果是否正常。
1.2 打包 .less 資源
??同樣在?src?下新建一個?index.less?文件,并將其引入到?index.js?中:
??我們知道?less?文件是不能被瀏覽器直接解析的,需要編譯成?css?文件。webpack?同樣需要將其進行編譯,這里需要借助?less?和?less-loader:
npm?i?less?less-loader?-D??接下來我們修改配置文件:
rules: [// 詳細配置 { test: /\.less$/, // less-loader: 將 .less 文件編譯成 .css 文件 use: ["style-loader", "css-loader", "less-loader"] }]??然后打包:
1.3 打包 .sass 資源
??sass?和?less?的處理步驟十分類似,只不過負責編譯?sass?文件需要:?sass?和?sass-loader:
npm?i?sass?sass-loader?-D??同樣修改配置文件以匹配?sass?文件:
rules: [// 詳細配置 { test: /\..sass$/, // sass-loader: 將 .sass 文件編譯成 .css 文件 use: ["style-loader", "css-loader", "sass-loader"] }]??然后打包:
1.4 總結
??關于?PostCSS?和?Stylus?文件的處理這里就不加掩飾,我們可以通過總結一下上方三種樣式資源的處理方式,得出關于資源編譯的特性,無論處理任何資源都可以按照這個步驟來進行
Step 1:下載安裝用于處理資源的相關?loader;
Step 2:?通過?module.rules.resource?提供的各種方式來匹配需要處理的資源;
Step 3:?使用?module.rules.use?等來加載負責處理匹配到資源的?loader;
Step 4:?如有需要,可以通過?options?來設置對?loader?的配置;
需要特別注意,?loader?在引入時對順序是有要求的!!!
??以?.sass?文件為例,sass-loader?負責將?.sass?文件編譯為?.css?文件;接著?css-loader?將?.css?文件轉化為?CommonJS?模塊加載到相應的?js?文件中;最后?style-loader?將?js?文件中相應的?css?通過??標簽加載到頁面中,所以?use?中的內容要嚴格按照這個順序:
use:?["style-loader",?"css-loader",?"sass-loader"]??最后附上最終的?webpack.config.js?文件代碼:
/** * @filename: webpack.config.js * @Author: wang * @Description: webpack的配置文件,采用 CommonJS 語法 */// 引入 NodeJS 中的 Path 模塊暴露的 resolve 方法來處理路徑問題 // 同樣可以使用 join 方法來拼接路徑const { resolve } = require('path');// CommonJS 語法暴露配置文件module.exports = { // 開發模式 mode: "development", // 入口文件 entry: { index: "./src/index.js" }, // 打包出口 output: { // 設置打包后的文件名為 入口名 - chunkhash 前八位 .js filename: '[name]-[chunkhash:8].js', // 設置打包后的文件位于 dist 文件夾 // __dirname 為 NodeJs 中的變量,代表當前文件的絕對目錄 path: resolve(__dirname, "dist") }, // loader 配置 module: { rules: [ // 詳細配置 { // 使用正則匹配所有 .css 結尾的文件 test: /\.css$/, // 通過 style-loader 和 css-loader 處理匹配到的文件 // loader 的執行順序是從下到上的 千萬注意 loader 的書寫順序 use: [ // 通過 style 標簽將 JS 文件中的 css 資源添加到頁面的 head 中 "style-loader", // 將 css 文件變成 CommonJS 的模塊資源,加載到 JS 文件中 "css-loader" ], }, { test: /\.less$/, // less-loader: 將 .less 文件編譯成 .css 文件 use: ["style-loader", "css-loader", "less-loader"] }, { test: /\.scss$/, // sass-loader: 將 .sass 文件編譯成 .css 文件 use: ["style-loader", "css-loader", "sass-loader"] }, ] }, // 插件 plugins: []}項目目錄及package.json:二、提取
2.1 提取樣式到單獨 css 文件
??我們發現,webpack?在打包完成后,css?資源被打包到了?js?當中,并沒有將表現層和行為層進行分離,顯然,這并不符合我們的開發習慣,在慢網速下也會由于?js?文件加載緩慢造成樣式丟失等問題。這個時候,我們需要借助一個插件將?css?文件單獨提取出來:
npm?i?mini-css-extract-plugin?-D??安裝完畢后我們修改一下項目的目錄,并創建一些文件:
??接下來修改配置文件,將插件引入進來:
/** * @filename: webpack.config.js * @Author: wang * @Description: webpack的配置文件,采用 CommonJS 語法 */// 與 loader 不同,使用插件需要提前引入const MiniCssExtractPlugin = require('mini-css-extract-plugin');const { resolve } = require('path');module.exports = { // 開發模式 mode: "development", // 多入口文件 entry: { a: "./src/js/a.js", b: "./src/js/b.js" }, // 打包出口 output: { filename: '[name]-[chunkhash:8].js', path: resolve(__dirname, "dist") }, // loader 配置 module: { rules: [ { test: /\.css$/, use: [ // 這里我們需要使用 MiniCssExtractPlugin 取代 style-loader // style-loader : 將 css 通過 style 標簽添加到頁面中 // MiniCssExtractPlugin.loader: 將 JS 文件中的 css 資源提取到單獨的 css 文件中 //MiniCssExtractPlugin.loader, { loader:MiniCssExtractPlugin.loader, options:{ // 如果打包時背景圖片等資源的路徑與開發時不一致 可以通過 publicPath 設置公共路徑 publicPath:"" } }, "css-loader" ], }, ] }, // 插件 plugins: [ // 插件都需要通過 new 的方式來調用 new MiniCssExtractPlugin({ // 設置生成的文件路徑及文件名 filename: "/static/css/[name]-[chunkhash:8].css" }) ]}??搞定,我們來執行一下打包命令:
??我們發現?a.css?和?b.css?都被打包成了單獨的文件,但?c.css?卻被分別打包進了兩個文件內。
2.2 打包公共樣式
??在工作中我們常常會將公共部分提取出來,單獨引用著一個文件,在上方的實例中,c.css?就是一個公共資源,應該單獨打包,而不是分別打包到每個引用他的文件內,這里需要借助另外一個插件:?SplitChunksPlugin;
??SplitChunksPlugin?是?webpack4.0?以上版本的內置插件,無須安裝,可以直接配置使用:
module.exports = { // 省略...... optimization: { splitChunks: { cacheGroups: { //打包公共模塊 commons: { // initial 表示提取每個入口文件中的公共部分 chunks: 'initial', // 設置公共部分提取的最少文件數為 2 minChunks: 2, // 設置提取公共部分最小的大小 // 假設值為 1* 1024 則表示 1KB 以下的文件不參與提取 minSize: 0, // 提取出來的文件命名 name: 'common' } } } }}??我們刪除掉之前打包出的文件夾,重新進行打包:
??這時候,我們已經成功的將公共樣式文件單獨打包成了一個文件,最后的?webpack.config.js?文件代碼:
/** * @filename: webpack.config.js * @Author: wang * @Description: 通過 mini-css-extract-plugin 提取樣式資源到單獨的文件 */// 與 loader 不同,使用插件需要提前引入const MiniCssExtractPlugin = require('mini-css-extract-plugin');const { resolve } = require('path');module.exports = { // 開發模式 mode: "development", // 入口文件 entry: { a: "./src/js/a.js", b: "./src/js/b.js" }, // 打包出口 output: { filename: '[name]-[chunkhash:8].js', path: resolve(__dirname, "dist/static/js") }, // loader 配置 module: { rules: [ { test: /\.css$/, use: [ // 這里我們需要使用 MiniCssExtractPlugin 取代 style-loader // style-loader : 將 css 通過 style 標簽添加到頁面中 // MiniCssExtractPlugin.loader: 將 JS 文件中的 css 資源提取到單獨的 css 文件中 MiniCssExtractPlugin.loader, "css-loader" ], }, ] }, // 插件 plugins: [ // 插件都需要通過 new 的方式來調用 new MiniCssExtractPlugin({ // 設置生成的文件路徑及文件名 filename: "../css/[name]-[chunkhash:8].css" }) ], optimization: { splitChunks: { cacheGroups: { //打包公共模塊 commons: { // initial 表示提取每個入口文件中的公共部分 chunks: 'initial', // 設置公共部分提取的最少文件數為 2 minChunks: 2, // 設置提取公共部分最小的大小 // 假設值為 1* 1024 則表示 1KB 以下的文件不參與提取 minSize: 0, // 提取出來的文件命名 name: 'common' } } } }}三、壓縮
??為了減少文件大小,提高訪問速度,一般我們會在上線時對文件進行壓縮處理,壓縮?css?文件時,需要安裝一個插件:
npm?i?optimize-css-assets-webpack-plugin?-D??安裝完畢后,我們只需要安裝插件的使用方法將其引入即可:
// 與 loader 不同,使用插件需要提前引入// 提取 css 插件const MiniCssExtractPlugin = require('mini-css-extract-plugin');// 壓縮 css 插件const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');const { resolve } = require('path');module.exports = { // 省略...... plugins: [ // 插件都需要通過 new 的方式來調用 new MiniCssExtractPlugin({ // 設置生成的文件路徑及文件名 // filename: resolve(__dirname, "./css/[name]-[chunkhash:8].css") filename: "../css/[name]-[chunkhash:8].css" }), // 直接引入即可 new OptimizeCssAssetsPlugin() ]}四、消除無用 css
??我們在開發時一般都會引入各種框架來輔助開發,而我們往往只會用到其中的一部分,而不是所有的樣式,這就造成了代碼冗余。就算是我們自己寫的樣式,有時候也會因為頁面更新等原因導致忘記刪除無用的部分,現在我們可以借用?webpack?將無用部分直接去除:
npm?i?purifycss-webpack?purify-css?-D??因為涉及到?css?的引用,所以我們還需要對?html?資源進行處理:
npm?i?html-webpack-plugin?-D??關于使用?html-webpack-plugin?打包處理?html?的內容,我們在后面的章節另行介紹,這里先知道這個插件用于打包?html?內容,自動引入文件即可。
??引入完畢后,我們給?a.css | b.css?隨意添加一些樣式,:
??然后修改配置文件:
// 省略......plugins: [ // 打包 html 資源 new HtmlWebpackPlugin({ // 復制 './src/a.html' 文件結構 template: './src/a.html', // 在打包生成的頁面中自動引入 a 模塊輸出的所有資源 chunks: ['a'], // 設置打包路徑及文件名 filename: resolve(__dirname,"./dist/a.html") }), new HtmlWebpackPlugin({ template: './src/b.html', chunks: ['b'], filename: resolve(__dirname,"./dist/b.html") }), // 去除無用 css new PurifyPlugin({ // 通過 NodeJs 中的 glob 模塊掃碼 html 文件,找出沒有用到的樣式 paths: glob.sync(resolve(__dirname, 'src/*.html')) })],??修改完成后打包查看輸出結果:
??我們發現直接隨意添加的兩個類名由于并沒有在頁面中引入,所以直接被?webpack?干掉了。
五、兼容性處理
??我們知道有些屬性在各個瀏覽器中擁有不同的前綴,我們在開發時需要將每一個瀏覽器的前綴都加上,例如說我們常用的彈性布局?display:flex,為了處理兼容性常常需要寫成以下形式:
.box1{ display: -moz-box; /* Firefox */ display: -ms-flexbox; /* IE10 */ display: -webkit-box; /* Safari */ display: -webkit-flex; /* Chrome, WebKit */ display: flex;}??這讓我們在開發時還需要手動添加額外的屬性,感覺上十分的麻煩,所以這時候,我們可以選擇通過?webpack?來處理:
npm?i?postcss?postcss-loader?postcss-preset-env?-D??在之前版本中,相關配置可以直接寫在?loader?中:
// 省略...rules: [ { loader: 'postcss-loader', options: { // 固定寫法 使用 postcss 方式識別 ident: 'postcss', plugins: () => [ // 引用 postcss-preset-env 插件 require('postcss-preset-env')() ] } }]??但目前版本的?postcss?需要將配置分別寫在?loader?和?plugins?中:
// 省略... module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader", // postcss-loader 需要在 css-loader 前, less/sass-loader 后引用 "postcss-loader" ], }, ]}plugins: [ require('postcss-preset-env')()]??修改完配置文件后,還需要我們提供一個相應的配置文件,決定如何處理兼容性,之前版本可以直接在?package.json?中聲明?browserslist?屬性即可:
"browserslist": [ "defaults", "not ie < 10", "last 2 versions", "> 1%", "iOS 7", "last 3 iOS versions"??]??但更新后需要在項目根目錄新建一個?postcss.config.js?的配置文件來進行設置:
/** * @filename: postcss.config.js * @Author: wang * @Description: postcss 配置文件 指示那些情況下需要處理 那些情況不需要處理兼容性 */module.exports = { plugins: [ require('autoprefixer')({ "browsers": [ "defaults", "not ie < 11", "last 2 versions", "> 1%", "iOS 7", "last 3 iOS versions" ] }) ]}??如果還是想將相應內容寫到?package.json?中,則需要將?postcss.config.js?修改為:
/** * @filename: postcss.config.js * @Author: wang * @Description: postcss 配置文件 指示那些情況下需要處理 那些情況不需要處理兼容性 */module.exports = { plugins: [ require('autoprefixer')() ]}??打包完成后,我們發現?webpack?已經為我們自動加上了前綴。
??以上就是本篇博客的內容,博客內容較長,建議無基礎的同學分段閱讀。關于對?css?資源的處理,大體上就是以上的內容,博客中的代碼位于?碼云Git倉庫,如有需要可自行前往下載。
?? 下一篇我們來介紹一下?webpack?對?js?資源的處理。
博客中的代碼位于?碼云Git倉庫,如有需要可自行前往下載。點擊查看原文即可跳轉到?webpack 系列文章目錄。感謝大家的觀看及支持,我們下篇博客再見!如果有問題需要老王幫忙或者想看關于某個主題的文章,也可以通過留言等方式來聯系老王。
每篇文章純屬個人經驗觀點,如有錯誤疏漏歡迎指正。轉載請附帶作者信息及出處。您的評論和關注是我更新的動力!
點擊查看原文跳轉到?博客? ? ? ??點下再看,少個BUG
總結
以上是生活随笔為你收集整理的css初始化样式文件_前端必备技能 webpack 4. webpack处理CSS资源的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python字符串split_「干货」P
- 下一篇: fegin需要实现类_深入理解JVM(六