gulp構(gòu)建小程序的方法步驟
目前來(lái)說(shuō),對(duì)于構(gòu)建小程序的,類似taro這些框架,生態(tài)已經(jīng)挺完善的了,沒(méi)有什么必要再搞一套來(lái)折騰自己。但是,我司的小程序,是很早之前就開發(fā)的,我們負(fù)責(zé)人當(dāng)時(shí)信不過(guò)這些開源的框架,于是自己用webpack搞了一套框架,但有一個(gè)比較嚴(yán)重的問(wèn)題,有一些文件依賴重復(fù)打包了,導(dǎo)致小程序包體積比較大。
持續(xù)了一個(gè)多月,主包體積在2M左右徘徊,開發(fā)都很難做下去。我們負(fù)責(zé)人終于受不了了,給了我個(gè)任務(wù),讓我寫一個(gè)構(gòu)建小程序的工具,減少小程序包體積。
我們現(xiàn)在的框架對(duì)比一下原生小程序,其實(shí)差別不大,無(wú)非就是
ts => js sass=>wxss wxml=>wxml json=>json
由于我司小程序基礎(chǔ)庫(kù)是1.9.8的,不支持構(gòu)建npm,所以node_modules的依賴包以及依賴路徑需要自己處理,于是寫了一個(gè)babel插件 babel-plugin-copy-npm。
這么一想,其實(shí)不難,而且單文件編譯,那不是gulp的強(qiáng)項(xiàng)嗎?。?!
最終效果:
而且由于增量更新,只修改改變的文件,所以編譯的速度非???。
項(xiàng)目地址:https://github.com/m-Ryan/ry-wx
最終流程大概如下:清除dist目錄下的文件 => 編譯文件到dist目錄下=> 開發(fā)模式監(jiān)聽(tīng)文件更改,生產(chǎn)環(huán)境壓縮文件。
一、清除dist目錄下的文件 (clean.js)
const del = require('del'); const fs = require('fs'); const path = require('path'); const cwd = process.cwd(); module.exports = function clean() { if (!fs.existsSync(path.join(cwd, 'dist'))) { fs.mkdirSync('dist'); return Promise.resolve(null); } return del([ '*', '!npm' ], { force: true, cwd: path.join(cwd, 'dist') }); };
二、編譯文件
1.編譯typescript(compileJs.js)
const gulp = require('gulp'); const { babel } = require('gulp-load-plugins')(); const path = require('path'); const cwd = process.cwd(); module.exports = function compileJs(filePath) { let file = 'src/**/*.ts'; let dist = 'dist'; if (typeof filePath === 'string') { file = path.join(cwd, filePath); dist = path.dirname(file.replace(/src/, 'dist')); } return gulp.src(file).pipe(babel()).pipe(gulp.dest(dist)); };
2.編譯sass(compileSass.js)
const gulp = require('gulp'); const { sass, postcss, rename } = require('gulp-load-plugins')(); const path = require('path'); const cwd = process.cwd(); const plugins = [ require('autoprefixer')({ browsers: [ 'ios >= 8', 'ChromeAndroid >= 53' ], remove: false, add: true }), require('postcss-pxtorpx')({ multiplier: 2, propList: [ '*' ] }) ]; module.exports = function compileSass(filePath) { let file = 'src/**/*.scss'; let dist = 'dist'; if (typeof filePath === 'string') { file = path.join(cwd, filePath); dist = path.dirname(file.replace(/src/, 'dist')); } return gulp .src(file) .pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError)) .pipe(postcss(plugins)) .pipe( rename({ extname: '.wxss' }) ) .pipe(gulp.dest(dist)); };
編譯json,wxml,由于需要壓縮,所以需要分開處理
(copyJson.js)
const gulp = require('gulp'); module.exports = function copyJson() { let file = 'src/**/*.json'; let dist = 'dist'; if (typeof filePath === 'string') { file = path.join(cwd, filePath); dist = path.dirname(file.replace(/src/, 'dist')); } return gulp.src([ file ]).pipe(gulp.dest(dist)); };
(copyWxml.js)
const gulp = require('gulp'); const minifyHtml = require('gulp-html-minify'); module.exports = function copyWxmlFiles() { let file = 'src/**/*.wxml'; let dist = 'dist'; if (typeof filePath === 'string') { file = path.join(cwd, filePath); dist = path.dirname(file.replace(/src/, 'dist')); } return gulp.src(file).pipe(minifyHtml()).pipe(gulp.dest(dist)); };
4.拷貝其他靜態(tài)資源,例如字體、圖片
(copyAssets.js)
const gulp = require("gulp"); module.exports = function copyAssets() { let file = "src/**/**"; let dist = "dist"; if (typeof filePath === "string") { file = path.join(cwd, filePath); dist = path.dirname(file.replace(/src/, "dist")); } return gulp .src([ file, "!**/*.json", "!**/*.ts", "!**/*.js", "!**/*.scss", "!**/*.wxml" ]) .pipe(gulp.dest(dist)); };
5.引入文件(gulpfile.js)
const gulp = require("gulp"); const clean = require("./build/clean"); const compileJs = require("./build/compileJs"); const compileSass = require("./build/compileSass"); const copyJson = require("./build/copyJson"); const copyWxml = require("./build/copyWxml"); const copyAssets = require("./build/copyAssets"); const fs = require("fs-extra"); const path = require("path"); const chalk = require("chalk"); const cwd = process.cwd(); const dayjs = require("dayjs"); const tasks = [ clean, gulp.parallel([compileJs, compileSass, copyJson, copyWxml]), copyAssets ]; if (process.env.NODE_ENV === "development") { tasks.push(watch); } gulp.task("default", gulp.series(tasks)); gulp.task("watch", watch); function watch() { console.log(chalk.blue(`正在監(jiān)聽(tīng)文件... ${getNow()}`)); const watcher = gulp.watch("src/**/**"); watcher.on("change", function(filePath, stats) { compile(filePath); }); watcher.on("add", function(filePath, stats) { compile(filePath); }); watcher.on("unlink", function(filePath, stats) { let distFile = filePath.replace(/^src\b/, "dist"); let absolutePath = ""; if (distFile.endsWith(".ts")) { distFile = distFile.replace(/.ts$/, ".js"); } else if (distFile.endsWith(".scss")) { distFile = distFile.replace(/.scss$/, ".wxss"); } absolutePath = path.join(cwd, distFile); if (fs.existsSync(absolutePath)) { fs.unlinkSync(absolutePath); console.log( chalk.yellow(`刪除文件:${path.basename(distFile)} ${getNow()}`) ); } }); } function compile(filePath) { console.info( chalk.green(`編譯完成:${path.basename(filePath)} ${getNow()}`) ); if (filePath.endsWith(".ts")) { compileJs(filePath); } else if (filePath.endsWith(".scss")) { compileSass(filePath); } else if (filePath.endsWith(".wxml")) { copyWxml(filePath); } else if (filePath.endsWith(".json")) { copyJson(filePath); } else { copyAssets(filePath); } } function getNow() { return dayjs().format("HH:mm:ss"); }
babel的配置如下.babelrc.js
const babelOptions = { presets: [ '@babel/preset-typescript', [ '@babel/env' ] ], plugins: [ 'lodash', [ '@babel/plugin-proposal-decorators', { legacy: true } ], 'babel-plugin-add-module-exports', [ '@babel/plugin-transform-runtime', { corejs: false, helpers: true, regenerator: true, useESModules: false } ], [ 'module-resolver', { root: [ '.' ], alias: { '@': './src' } } ], [ 'babel-plugin-copy-npm', { rootDir: 'src', outputDir: 'dist', npmDir: 'npm', format: 'cjs', strict: false, minify: true, loose: true, cache: true } ] ] }; if (process.env.NODE_ENV === 'production') { babelOptions.presets.unshift([ 'minify', { mangle: { exclude: [ 'wx', 'module', 'exports', '__wxConfigx', 'process', 'global' ] }, keepFnName: true } ]); } module.exports = babelOptions;
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript實(shí)現(xiàn)時(shí)鐘特效
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)時(shí)鐘特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06移動(dòng)設(shè)備手勢(shì)事件庫(kù)Touch.js使用詳解
這篇文章主要介紹了移動(dòng)設(shè)備手勢(shì)事件庫(kù)Touch.js的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08多個(gè)上傳文件用js驗(yàn)證文件的格式和大小的方法(推薦)
下面小編就為大家?guī)?lái)一篇多個(gè)上傳文件用js驗(yàn)證文件的格式和大小的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03js中的數(shù)組轉(zhuǎn)樹型結(jié)構(gòu)方式
這篇文章主要介紹了js中的數(shù)組轉(zhuǎn)樹型結(jié)構(gòu)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06javascript實(shí)現(xiàn)全角與半角字符的轉(zhuǎn)換
這篇文章主要介紹了javascript實(shí)現(xiàn)全角與半角字符的轉(zhuǎn)換的相關(guān)代碼與知識(shí)點(diǎn)分享,需要的朋友可以參考下2015-01-01如何用js實(shí)現(xiàn)判斷是否是小數(shù)
這篇文章主要給大家介紹了關(guān)于如何用js實(shí)現(xiàn)判斷是否是小數(shù)的相關(guān)資料,文中介紹了如何通過(guò)使用isNaN()函數(shù)和使用正則表達(dá)式來(lái)解決,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2024-04-04