From fd7e7112fbc096950036c7bdbf8b04c0bdf8b835 Mon Sep 17 00:00:00 2001 From: Mervin Date: Sun, 29 Sep 2024 16:08:19 +0800 Subject: [PATCH] perf(core): Import 'gulp-renew' package for string replacement. --- packages/core/build/html.js | 43 +++++-------- packages/core/build/script.js | 32 +++------- packages/core/build/style.js | 53 +++++++--------- packages/core/package.json | 3 +- packages/core/plugins/renew.js | 113 --------------------------------- 5 files changed, 49 insertions(+), 195 deletions(-) delete mode 100644 packages/core/plugins/renew.js diff --git a/packages/core/build/html.js b/packages/core/build/html.js index 70e0d4d..9c9c2dc 100644 --- a/packages/core/build/html.js +++ b/packages/core/build/html.js @@ -1,9 +1,6 @@ const gulp = require('gulp') const rename = require('gulp-rename') -const { - isPlainObject, - injectEnv -} = require('@pipflow/utils') +const { isPlainObject, injectEnv } = require('@pipflow/utils') const { pipeline, onDone } = require('../base/utils') const { htmlMinifyOptions } = require('../base/defaults') @@ -13,7 +10,7 @@ const { createSrcOptions, outputFiles, plumber, putProcesses, readManifest } = r * html 模板引擎 * @param {string} compiler 模板引擎name * @param {object} compilerOptions 配置项 - * @returns + * @returns */ function templater(compiler, compilerOptions = {}) { const { data = {} } = compilerOptions @@ -37,14 +34,14 @@ function templater(compiler, compilerOptions = {}) { nunjucks() { // nunjucks.compile(data?, options?) return require('gulp-nunjucks')(data, compilerOptions) - } + }, } return templaterMap[compiler]?.() } /** * HTML 处理任务 - * + * * @param {Object} options - 配置项 * @param {string|string[]|string[][]|Object.} options.input - 输入文件路径 * @param {string} [options.dest] - 输出目录 @@ -61,19 +58,12 @@ function templater(compiler, compilerOptions = {}) { * @throws {Error} 如果`options.input`未定义,则抛出错误 */ module.exports = function htmlTask(options = {}, done) { - const { - input, - dest, - compiler, - compilerOptions, - minify: htmlMinify, - alias - } = options - + const { input, dest, compiler, compilerOptions, minify: htmlMinify, alias } = options + if (!input) { throw new Error('input is required') } - + const processes = [] const srcOptions = createSrcOptions(options.base, htmlTask) @@ -90,10 +80,10 @@ module.exports = function htmlTask(options = {}, done) { processes.push(rendered) } } - + // 4. replace 替换别名 (在模板编译后,避免路径不会被替换) if (isPlainObject(alias) || Array.isArray(alias)) { - processes.push(require('../plugins/renew')(alias)) + processes.push(require('gulp-renew')(alias)) } // 5. 自定义处理流程 @@ -103,19 +93,23 @@ module.exports = function htmlTask(options = {}, done) { if (options.assetsInlineLimit?.limit > 0) { processes.push(require('gulp-dataurl')(options.assetsInlineLimit)) } - + // 6. 文件指纹处理 const manifest = readManifest(options) if (manifest) { processes.push(require('gulp-rev-rewrite')({ manifest })) } - + // 7. 重命名 processes.push(rename({ extname: '.html' })) // 8. 压缩处理 if (htmlMinify) { - const minifyOptions = Object.assign({}, htmlMinifyOptions, isPlainObject(htmlMinify) ? htmlMinify : {}) + const minifyOptions = Object.assign( + {}, + htmlMinifyOptions, + isPlainObject(htmlMinify) ? htmlMinify : {} + ) processes.push(require('../plugins/htmlMinifier')(minifyOptions)) } @@ -126,8 +120,5 @@ module.exports = function htmlTask(options = {}, done) { sourcemap: false, }) - return pipeline( - gulp.src(input, srcOptions), - processes - ).on('end', onDone(done)) + return pipeline(gulp.src(input, srcOptions), processes).on('end', onDone(done)) } diff --git a/packages/core/build/script.js b/packages/core/build/script.js index ec299be..f75958c 100644 --- a/packages/core/build/script.js +++ b/packages/core/build/script.js @@ -6,10 +6,7 @@ const uglifyjs = require('gulp-terser') const sourcemaps = require('gulp-sourcemaps') const filter = require('gulp-filter') const merge = require('merge2') -const { - isPlainObject, - injectEnv -} = require('@pipflow/utils') +const { isPlainObject, injectEnv } = require('@pipflow/utils') const { pipeline, onDone } = require('../base/utils') const { outputFiles, createSrcOptions, plumber, putProcesses, getBasePath } = require('./comm') @@ -18,19 +15,15 @@ const { outputFiles, createSrcOptions, plumber, putProcesses, getBasePath } = re * 处理 script文件 (非 module) * @param {object} options 配置项 * @param {Function} done 回调 - * @returns + * @returns */ function compileScript(options = {}, done) { if (!options.input) { throw new Error('input is required') } - const { - input, - alias, - minify: jsMinify - } = options - + const { input, alias, minify: jsMinify } = options + const processes = [] const jsFilter = filter('*.{js,mjs}', { restore: true }) const srcOptions = createSrcOptions(options.base, compileScript) @@ -39,7 +32,7 @@ function compileScript(options = {}, done) { // 统一入口方式 (input支持 `string`, `array`, `object`) const entries = ( isPlainObject(input) - ? Object.keys(input).map(name => ({ name, file: input[name] })) + ? Object.keys(input).map((name) => ({ name, file: input[name] })) : [{ name: '', file: input }] ).map(({ name, file }) => { const baseProcesses = [] @@ -57,7 +50,7 @@ function compileScript(options = {}, done) { // 4. replace 别名替换 if (isPlainObject(alias) || Array.isArray(alias)) { - baseProcesses.push(require('../plugins/renew')(alias)) + baseProcesses.push(require('gulp-renew')(alias)) } // 5. 合并文件 @@ -65,10 +58,7 @@ function compileScript(options = {}, done) { baseProcesses.push(concat(path.join(basePath, `${name}.js`))) } - return pipeline( - gulp.src(file, name ? { ...srcOptions, base: '.' } : srcOptions), - baseProcesses - ) + return pipeline(gulp.src(file, name ? { ...srcOptions, base: '.' } : srcOptions), baseProcesses) }) // 1. 自定义处理流程 @@ -107,17 +97,13 @@ function compileScript(options = {}, done) { ...options, filter: jsFilter, }) - - return pipeline( - merge(...entries), - processes - ).on('end', done) + return pipeline(merge(...entries), processes).on('end', done) } /** * Javascript 处理任务 - * + * * @param {Object} options - 配置项 * @param {string|string[]|string[][]|Object.} options.input - 输入文件路径 * @param {string} [options.dest] - 输出目录 diff --git a/packages/core/build/style.js b/packages/core/build/style.js index 5591370..770b7d7 100644 --- a/packages/core/build/style.js +++ b/packages/core/build/style.js @@ -8,10 +8,7 @@ const filter = require('gulp-filter') const postcss = require('../plugins/postcss') const postcssEnv = require('postcss-preset-env') -const { - isPlainObject, - injectEnv -} = require('@pipflow/utils') +const { isPlainObject, injectEnv } = require('@pipflow/utils') const { pipeline, onDone } = require('../base/utils') const { sassDefaultOptions } = require('../base/defaults') @@ -21,12 +18,12 @@ const { plumber, putProcesses, getBasePath, - readManifest + readManifest, } = require('./comm') /** * CSS样式 处理任务 - * + * * @param {Object} options - 配置项 * @param {string|string[]|string[][]|Object.} options.input - 输入文件路径 * @param {string} [options.dest] - 输出目录 @@ -44,13 +41,7 @@ const { * @throws {Error} 如果`options.input`未定义,则抛出错误 */ module.exports = function styleTask(options = {}, done) { - const { - input, - compiler, - compilerOptions, - minify: cssMinify, - alias - } = options + const { input, compiler, compilerOptions, minify: cssMinify, alias } = options if (!input) { throw new Error('input is required') @@ -70,7 +61,7 @@ module.exports = function styleTask(options = {}, done) { */ const entries = ( isPlainObject(input) - ? Object.keys(input).map(name => ({ name, file: input[name] })) + ? Object.keys(input).map((name) => ({ name, file: input[name] })) : [{ name: '', file: input }] ).map(({ name, file }) => { const baseProcesses = [] @@ -93,17 +84,21 @@ module.exports = function styleTask(options = {}, done) { // 5.2 CSS预处理器 if (compiler === 'sass' || compiler === 'scss') { const sass = require('gulp-sass')(require('sass')) - const _sassOptions = Object.assign({}, sassDefaultOptions, compilerOptions?.preprocessorOptions) + const _sassOptions = Object.assign( + {}, + sassDefaultOptions, + compilerOptions?.preprocessorOptions + ) baseProcesses.push(sass(_sassOptions).on('error', sass.logError)) } else if (compiler === 'less') { baseProcesses.push(require('gulp-less')(compilerOptions?.preprocessorOptions || {})) } else if (compiler === 'stylus') { baseProcesses.push(require('gulp-stylus')(compilerOptions?.preprocessorOptions || {})) } - + // 4. replace 别名替换 if (isPlainObject(alias) || Array.isArray(alias)) { - baseProcesses.push(require('../plugins/renew')(alias)) + baseProcesses.push(require('gulp-renew')(alias)) } // 6. 合并文件 @@ -111,19 +106,16 @@ module.exports = function styleTask(options = {}, done) { baseProcesses.push(concat(path.join(basePath, `${name}.css`))) } - return pipeline( - gulp.src(file, name ? { ...srcOptions, base: '.' } : srcOptions), - baseProcesses - ) + return pipeline(gulp.src(file, name ? { ...srcOptions, base: '.' } : srcOptions), baseProcesses) }) /*************************************************************** * 统一自定义处理流程 - */ + */ // 1. 自定义处理流程 putProcesses(processes, options.plugins) - + // 2. base64 处理 if (options.assetsInlineLimit?.limit > 0) { processes.push(require('gulp-dataurl')(options.assetsInlineLimit)) @@ -142,20 +134,19 @@ module.exports = function styleTask(options = {}, done) { const minifyOptions = isPlainObject(cssMinify) ? cssMinify : {} postcssPlugins.push(require('cssnano')(minifyOptions)) } - processes.push(postcss({ - _plugins: postcssPlugins - })) + processes.push( + postcss({ + _plugins: postcssPlugins, + }) + ) // 3. 文件指纹处理 & sourcemaps & 输出文件 outputFiles(processes, { ...options, - filter: cssFilter + filter: cssFilter, }) - return pipeline( - merge(...entries), - processes - ).on('end', onDone(done)) + return pipeline(merge(...entries), processes).on('end', onDone(done)) } /** 任务整体流程 diff --git a/packages/core/package.json b/packages/core/package.json index baa70b6..61e08ac 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -63,6 +63,7 @@ "gulp-plumber": "^1.2.1", "gulp-pug": "^5.0.0", "gulp-rename": "^2.0.0", + "gulp-renew": "workspace:^", "gulp-rev": "^9.0.0", "gulp-rev-rewrite": "^5.0.0", "gulp-sass": "^5.1.0", @@ -71,8 +72,6 @@ "gulp-terser": "^2.1.0", "gulp-zip": "^5.1.0", "html-minifier-terser": "^7.2.0", - "istextorbinary": "^9.5.0", - "replacestream": "^4.0.3", "merge2": "^1.4.1", "plugin-error": "^2.0.1", "postcss": "^8.4.47", diff --git a/packages/core/plugins/renew.js b/packages/core/plugins/renew.js deleted file mode 100644 index 49336c8..0000000 --- a/packages/core/plugins/renew.js +++ /dev/null @@ -1,113 +0,0 @@ -'use strict'; - -const Transform = require('stream').Transform; -const rs = require('replacestream'); -const istextorbinary = require('istextorbinary'); - -const PLUGIN_NAME = 'gulp-renew'; - -const defaultOptions = { - skipBinary: true -} - -function isObject(obj) { - return Object.prototype.toString.call(obj) === '[object Object]'; -} - -/** - * Performs batch replacement on file contents - * @param {Array<{search: string|RegExp, replacement: string|Function}>} replacements - * @param {Object} options - */ -module.exports = function(replacements, options = {}) { - // Merge options - options = { - ...defaultOptions, - ...options - }; - - // 支持 {search: replacement} 对象形式 - if (isObject(replacements)) { - replacements = Object.keys(replacements).map(key => { - return { - search: key, - replacement: replacements[key] - } - }) - } - - if (!Array.isArray(replacements)) { - throw new TypeError(`[${PLUGIN_NAME}]: Expected an array of replacements`) - } - - // 支持 [[search, replacement]] 数组形式 - replacements = replacements.reduce((result, item) => { - if (isObject(item)) { - result.push(item) - } else if (Array.isArray(item) && item.length === 2) { - result.push({ - search: item[0], - replacement: item[1] - }) - } - return result - }, []) - - return new Transform({ - objectMode: true, - transform(file, enc, callback) { - if (file.isNull() || replacements.length === 0) { - return callback(null, file) - } - - function doReplace() { - if (file.isStream()) { - replacements.forEach(({ search, replacement }) => { - if (typeof replacement === 'function') { - replacement = replacement.bind({ file: file }) - } - file.contents = file.contents.pipe(rs(search, replacement)); - }) - return callback(null, file); - } - - if (file.isBuffer()) { - let content = file.contents.toString() - - replacements.forEach(({ search, replacement }) => { - if (search instanceof RegExp) { - content = content.replace(search, replacement) - } else { - const chunks = content.split(search) - - if (typeof replacement === 'function') { - content = chunks.reduce((result, chunk, index) => { - if (index === 0) return chunk - return result + replacement(search) + chunk - }, '') - } else { - content = chunks.join(replacement) - } - } - }) - - file.contents = Buffer.from(content) - return callback(null, file) - } - - callback(null, file) - } - - if (options.skipBinary) { - if (!istextorbinary.isText(file.path, file.contents)) { - callback(null, file) - } else { - doReplace() - } - return - } - - doReplace() - } - }) -}