詳解如何在微信小程序中愉快地使用sass
前言
在微信小程序中,css是用wxss來(lái)表示,但寫法基本一致。需要注意的是wxss擴(kuò)展了兩個(gè)特性,分別是:
- 尺寸單位
- 樣式導(dǎo)入
具體可參考wxss,此處不做過(guò)多贅述。
為了方便打包sass,我們使用gulp來(lái)處理我們的scss文件,將其轉(zhuǎn)換為wxss。
目錄結(jié)構(gòu)
在開發(fā)中,我們一般會(huì)有一個(gè)src源代碼目錄,一個(gè)dist目錄用來(lái)輸出我們打包的代碼。而本次講解用到的目錄結(jié)構(gòu)如下:
- build目錄用來(lái)配置我們的打包參數(shù),目前里面只有一個(gè)config.js文件
- dist目錄為打包輸出的目錄,也是小程序運(yùn)行的目錄
- gulpfile.js配置打包的任務(wù)
- src就是我們的源代碼目錄
src的目錄結(jié)構(gòu)如下:
安裝依賴
yarn add gulp gulp-sass gulp-rename gulp-replace gulp-tap gulp-clean -D
gulp和gulp-sass為打包sass必須,gulp-rename則負(fù)責(zé)把scss后綴改為wxss,gulp-replace負(fù)責(zé)內(nèi)容的替換(這個(gè)后面會(huì)講到),gulp-tap用來(lái)處理當(dāng)前執(zhí)行的文件,gulp-clean負(fù)責(zé)清除我們不需要的文件。
sass打包配置
gulp配置打包sass非常簡(jiǎn)單,代碼如下:
const gulp = require('gulp'); const sass = require('gulp-sass'); const rename = require('gulp-rename'); gulp.task('sass', () => gulp.src('./src/**/*.{scss,wxss}') .pipe(sass().on('error', sass.logError)) .pipe(rename({ extname: '.wxss' })) .pipe(gulp.dest('./dist')) );
這樣就可以完成了sass的配置,但是這樣會(huì)有問(wèn)題。前面講到了wxss是支持樣式導(dǎo)入的,也就是說(shuō)import語(yǔ)法wxss是支持的,但css不支持,因此sass打包會(huì)把import的文件打包到當(dāng)前文件,從而導(dǎo)致當(dāng)前文件的體積變大。由于微信限制單包代碼不能超過(guò)2M,因此當(dāng)css越寫越多的時(shí)候,這種打包方式勢(shì)必會(huì)使樣式文件越來(lái)越大。
解決import導(dǎo)入問(wèn)題
那如何解決import的導(dǎo)入問(wèn)題呢,其實(shí)也比較簡(jiǎn)單,說(shuō)白了就是sass處理的時(shí)候,讓其不處理import部分的語(yǔ)句就可以了。有兩種方式可以做到,第一種是改寫sass處理的源碼,當(dāng)遇到import語(yǔ)句時(shí)跳過(guò)。第二種是,在把文件交給sass處理前,我們先把import語(yǔ)句部分注釋掉,這樣sass處理的時(shí)候就會(huì)忽略了,當(dāng)sass處理完成后,再把注釋掉的語(yǔ)句打開即可。顯然第一種成本比較高,也不好維護(hù)。我們采用第二種,代碼如下:
const gulp = require('gulp'); const sass = require('gulp-sass'); const replace = require('gulp-replace'); const rename = require('gulp-rename'); const clean = require('gulp-clean'); const tap = require('gulp-tap'); const path = require('path'); const config = require('./build/config'); const hasRmCssFiles = new Set(); gulp.task('sass', () => gulp.src('./src/**/*.{scss,wxss}') .pipe(tap((file) => { // 當(dāng)前處理文件的路徑 const filePath = path.dirname(file.path); // 當(dāng)前處理內(nèi)容 const content = file.contents.toString(); // 找到filter的scss,并匹配是否在配置文件中 content.replace(/@import\s+['|"](.+)['|"];/g, ($1, $2) => { const hasFilter = config.cssFilterFiles.filter(item => $2.indexOf(item) > -1); // hasFilter > 0表示filter的文件在配置文件中,打包完成后需要?jiǎng)h除 if (hasFilter.length > 0) { const rmPath = path.join(filePath, $2); // 將src改為dist,.scss改為.wxss,例如:'/xxx/src/scss/const.scss' => '/xxx/dist/scss/const.wxss' const filea = rmPath.replace(/src/, 'dist').replace(/\.scss/, '.wxss'); // 加入待刪除列表 hasRmCssFiles.add(filea); } }); console.log('rm', hasRmCssFiles); })) .pipe(replace(/(@import.+;)/g, ($1, $2) => { const hasFilter = config.cssFilterFiles.filter(item => $1.indexOf(item) > -1); if (hasFilter.length > 0) { return $2; } return `/** ${$2} **/`; })) .pipe(sass().on('error', sass.logError)) .pipe(replace(/(\/\*\*\s{0,})(@.+)(\s{0,}\*\*\/)/g, ($1, $2, $3) => $3.replace(/\.scss/g, '.wxss'))) .pipe(rename({ extname: '.wxss', })) .pipe(gulp.dest('./dist')));
在處理import的時(shí)候,還有個(gè)地方是需要注意的。在sass中,import除了能引入css外,也可以引入變量,函數(shù)。因此,我們?cè)谔幚淼臅r(shí)候也需要注意區(qū)分,變量和函數(shù)最好有一個(gè)獨(dú)立的文件目錄存放,并且在import的時(shí)候,對(duì)于變量和函數(shù),是必須交給sass處理的,也就是不能注釋掉。因此,在上面的代碼中,我們可以看到,我們引入了build目錄下的config,其配置了sass變量和函數(shù)存放的位置,這樣我們?cè)诖虬臅r(shí)候,遇到這樣的import語(yǔ)句,我們就跳過(guò),交給sass處理,否則就代表其是引入了共用的樣式文件,這樣我們交給sass處理前,就先將其注釋掉,sass處理完成后再把注釋打開。另外,import的可能是一個(gè)scss文件,但在轉(zhuǎn)成wxss的時(shí)候,已經(jīng)將其后綴改為了wxss,因此,在將注釋打開的時(shí)候也需要更改相應(yīng)的引入,這也就是gulp-replace包的作用。config的配置如下:
module.exports = { cssFilterFiles: ['scss/var.scss'], };
清理無(wú)用的wxss文件
前面講了,我們?cè)趕ass中可能會(huì)定義一些變量,函數(shù),這些文件一會(huì)一并打包到dist目錄,但其內(nèi)容是空的,這時(shí)候我們就需要對(duì)其進(jìn)行清理,前面在打包過(guò)程中,我們有一個(gè)set變量hasRmCssFiles
記錄了相應(yīng)的文件,這樣我們遍歷這個(gè)變量即可刪除相應(yīng)的文件,代碼如下:
gulp.task('clean:wxss', () => { const arr = []; hasRmCssFiles.forEach((item) => { arr.push(item); }); return gulp.src(arr, { read: false }) .pipe(clean({ force: true })); });
總結(jié)
- wxss的特性
- sass打包配置以及如何處理import語(yǔ)句
- sass變量、函數(shù)的文件清理
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript實(shí)現(xiàn)即時(shí)通訊的 4 種方案
這篇文章主要給大家分享了JavaScript實(shí)現(xiàn)即時(shí)通訊的 4 種方案,其實(shí)就是服務(wù)端如何將數(shù)據(jù)推送到瀏覽器,下面詳細(xì)的文章內(nèi)容,需要的小伙伴參考一下,洗碗給對(duì)你有所幫助2022-02-02使用getBoundingClientRect方法實(shí)現(xiàn)簡(jiǎn)潔的sticky組件的方法
本文介紹這種組件的實(shí)現(xiàn)思路,并提供一個(gè)同時(shí)支持將sticky元素固定在頂部或底部的具體實(shí)現(xiàn),由于這種組件在網(wǎng)站中非常常見,所以有必要掌握它的實(shí)現(xiàn)方式,以便在有需要的時(shí)候基于它的思路寫出功能更多的組件出來(lái)2016-03-03JavaScript實(shí)現(xiàn)可拖拽的拖動(dòng)層Div實(shí)例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)可拖拽的拖動(dòng)層Div的方法,拖拽頁(yè)面中的div塊可實(shí)現(xiàn)div塊按照拖動(dòng)軌跡移動(dòng)的效果,涉及javascript鼠標(biāo)事件、頁(yè)面元素樣式結(jié)合事件函數(shù)動(dòng)態(tài)操作的相關(guān)技巧,需要的朋友可以參考下2015-08-08利用JS實(shí)現(xiàn)文字的聚合動(dòng)畫效果
這篇文章主要給大家介紹了利用JS如何實(shí)現(xiàn)文字的聚合動(dòng)畫效果,實(shí)現(xiàn)的效果非常不錯(cuò),類似粒子動(dòng)畫的效果,有需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01微信小程序中獲取用戶手機(jī)號(hào)授權(quán)登錄詳細(xì)步驟
這篇文章主要給大家介紹了關(guān)于微信小程序中獲取用戶手機(jī)號(hào)授權(quán)登錄的詳細(xì)步驟,在微信小程序中開發(fā)者可以通過(guò)微信提供的API接口實(shí)現(xiàn)用戶登錄和獲取用戶的手機(jī)號(hào),需要的朋友可以參考下2023-07-07JS 實(shí)現(xiàn)緩存算法的示例(FIFO/LRU)
這篇文章主要介紹了JS 實(shí)現(xiàn)緩存算法的示例(FIFO/LRU),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03bootstrap3中container與container_fluid外層容器的區(qū)別講解
.container與.container_fluid是bootstrap中的兩種不同類型的外層容器。這篇文章主要介紹了bootstrap3中container與container_fluid的區(qū)別,需要的朋友可以參考下2017-12-12