vue 開發常用工具及配置六:認識各種 loader

  • 2020 年 1 月 14 日
  • 筆記

本文大約 2400 字。

目錄

  • Webpack 的工作原理
  • loader 和 plugin 的區別
  • webpack 如何處理 css 文件
  • 三種樣式 sass/scss 和 less 的區別
  • 另一種定義全局 less 變數的方法
  • 源碼

Webpack 的工作原理

默認 webpack 只能處理 js 文件,如果在 js 文件中導入了 css 程式碼:

import './css/style.css';

程式將會報錯:

You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.

這與其工作原理有關。webpack 的工作原理是,從配置文件定義的模組列表開始,依賴文件類型選擇使用不同的 loader分別進行處理,最後將所有模組打包為bundle,這個 bundle 可由瀏覽器載入。

Webpack 用於完成打包任務的模組,主要有 loader 與 plugin。有一個類型就有一個 loader,如果 loader 缺失,程式就會報錯了。

loader 和 plugin 的區別

loader

用於對模組源碼的轉換,loader 描述了 webpack 如何處理非 js 模組,並且在 build 過程中引入這些依賴。loader 可以將文件從不同的語言轉換為 js,或者將內聯圖片轉換為 data URL。例如sass-loader,css-loader,style-loader等都是 loader。

在 webpack.config.js 中配置 loader 及 module.rules 可以指定多個 loader。

plugin

plugin 存在的目的在於解決 loader 無法實現的其他事,從打包優化和壓縮,到重新定義環境變數,可以用來處理各種各樣的任務。例如,CommonChunkPlugin 主要用於提取第三方庫和公共模組,避免 bundle 體積過大。

webpack 如何處理 css 文件

webpack 中默認只能打包 .js 類型的文件,無法打包其他類型文件。如果要打包非.js類型文件,需要手動安裝一些第三方 loader。下面看一下 webpack 在這方面是如何處理的。

在項目中用 npm 命令本地安裝 style-loader 和 css-loader 兩個包:

npm install style-loader css-loader --save--dev

在引用 style.css 文件時,將 import './css/style.css' 程式碼修改為:

import 'style-loader!css-loader!./style.css'")';

先經過 css-loader 和 style-loader 的處理,這樣css程式碼就能正常工作了。

這種方式每次引入時都需要加上「style-loader!css-loader!」,比較麻煩。除了這種方法,還可以在工程文件中一次性配置loader,研發中通常採用的是這種方式。

如果是 webpack 工程,打開webpack.config.js文件,在裡面新增一個配置節點module,在module對象中,有一個rules屬性,它是一個數組,裡面存放了所有第三方文件匹配和處理規則。如下程式碼匹配處理css文件:

module: { // 配置所有第三方loader 模組      rules: [ // 第三方模組的匹配規則        { test: /.css$/, use: ['style-loader', 'css-loader'] }, // 處理 CSS 文件的 loader      ]    }

注意:此處'style-loader'和'css-loader'順序不可替換。因為use中處理順序為從右向左。先用css-loader對css文件進行處理,將處理後的結果交給style-loader作進一步處理。其中,css-loader用於載入、解析css程式碼;style-loader生成一個內容為最終解析完的css程式碼的style標籤,放在html頁面的head內。

對於 vue cli3 創建的項目,在vue.config.js/configureWebpack內,添加如下配置:

config.module.rules.push({ test: /.css$/, use: ['style-loader', 'css-loader'] })

使用 less

首先是安裝插件:

yarn add style-loader css-loader less-loader less

然後修改 vue.config.js 配置:

// use less  config.module.rules.push({ test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader'] } )

因為調用順序是從右向左,所以先使用 less-loader 處理 less 程式碼,使之成為標準的css 程式碼,接下來的處理方式就和載入普通的css文件一致了。

這個顯式配置與默認配置有差異,導致編譯不通過。可以使用如下命令:

vue inspect -v --mode development > config-output.txt

查看默認配置。在 config-output.txt 文本中查看有關 less 的內容,與上面的配置內容有顯著差異。

使用 scss

使用scss與使用less類似。

先是安裝插件:

yarn add style-loader css-loader sass-loader node-sass

再是配置:

config.module.rules.push({ test: /.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }  )

因為項目中使用了 vuetify,在這個項目中混用scss會有編譯錯誤。可以採用同樣的方法,使用 vue inspect 指令導出默認配置查看差異所在。

三種樣式 sass/scss 和 less 的區別

Sass

Sass (Syntactically Awesome Stylesheets)是一種動態樣式語言,Sass語法屬於縮排語法,比css比多出好些功能(如變數、嵌套、運算,混入(Mixin)、繼承、顏色處理,函數等),更容易閱讀。

Scss

Sass的縮排語法,對於寫慣css前端的web開發者來說很不直觀,也不能將css程式碼加入到Sass裡面,因此sass語法進行了改良,Sass 3就變成了Scss(sassy css)。與原來的語法兼容,只是用{}取代了原來的縮進。

less

Less也是一種動態樣式語言. 對CSS賦予了動態語言的特性,如變數,繼承,運算, 函數. Less 既可以在客戶端上運行,也可在服務端運行。

1)編譯環境不一樣

Sass的安裝需要Ruby環境,是在服務端處理的,而Less是需要引入less.js來處理Less程式碼輸出css到瀏覽器,也可以在開發環節使用Less,然後編譯成css文件。

2)變數符不一樣

Less是@,而Scss是$,而且變數的作用域也不一樣。

3)Less沒有輸出設置

Sass提供4種輸出選項。

Sass提供4種輸出樣式,默認為nested

  • nested:嵌套縮進的css程式碼
  • expanded:展開的多行css程式碼
  • compact:簡潔格式的css程式碼
  • compressed:壓縮後的css程式碼

4)Sass支援條件語句

Sass 可以使用if{}else{},for{}循環等等。而Less不支援。

結論:Sass 功能雖比 Less 強大,但 Less 相對清晰明了,易於上手,對環境要求寬鬆。快速開發使用 less 足夠。

另一種定義全局 less 變數的方法

使用 less 不同避免地涉及多個樣式文件中的變數共享。在前面一篇文章「vue 開發常用工具及配置三」中,曾使用如下配置完成全局less變數的共享:

pluginOptions: {   'style-resources-loader': {     preProcessor: 'less',     patterns: [       path.resolve(__dirname, './src/assets/styles/variable.less'),     ],   },  },

這是一種使用 plugin 的解決方式,在vue.config.js使用 pluginOptions 通過配置達成。除了這種方法,還可以直接在vue.config.js/css.loaderOptions.less節點下,直接聲明全局變數:

loaderOptions: {    // 給 less-loader 傳遞 Less.js 相關選項    less:{      // http://lesscss.org/usage/#less-options-strict-units `Global Variables`      // `primary` is global variables fields name      globalVars: {        primaryBgColor: '#fff'      }    }  }

在vue組件中這樣使用:

<style lang="less" scoped>  button{   color: @theme-color;   background-color: @primaryBgColor;  }  </style>

源碼

https://git.code.tencent.com/shiqiaomarong/vue-go-rapiddev-example/tags/v202001022

參考鏈接

https://github.com/webpack-contrib/sass-loader

https://www.cnblogs.com/tangjiao/p/10429645.html

webpack的loader和plugin的區別

Vue – Mixing SASS with SCSS, with Vuetify as an Example

Vue – Mixing SASS with SCSS, with Vuetify as an Example

https://juejin.im/post/5d6ba287e51d453b5e465b80

Webpack中loader打包各種文件

https://www.cnblogs.com/wangpenghui522/p/5467560.html

[專欄]基於 vue+go 如何快速進行業務迭代?