From 3e01325efa4893a97d37e94ea58f20a2b9d5de16 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Fri, 12 Nov 2021 18:01:51 +0800 Subject: [PATCH 1/8] chore: saveCache --- packages/jsx2mp-loader/.prettierrc.js | 3 + packages/jsx2mp-loader/package.json | 3 + packages/jsx2mp-loader/src/app-loader.js | 1 + .../jsx2mp-loader/src/component-loader.js | 1 + packages/jsx2mp-loader/src/output.js | 12 ++- packages/jsx2mp-loader/src/page-loader.js | 1 + packages/jsx2mp-loader/src/script-loader.js | 1 + packages/jsx2mp-loader/src/utils/useCache.js | 82 +++++++++++++++++++ 8 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 packages/jsx2mp-loader/.prettierrc.js create mode 100644 packages/jsx2mp-loader/src/utils/useCache.js diff --git a/packages/jsx2mp-loader/.prettierrc.js b/packages/jsx2mp-loader/.prettierrc.js new file mode 100644 index 00000000..23c8ce5a --- /dev/null +++ b/packages/jsx2mp-loader/.prettierrc.js @@ -0,0 +1,3 @@ +const { getPrettierConfig } = require('@iceworks/spec'); + +module.exports = getPrettierConfig('rax'); diff --git a/packages/jsx2mp-loader/package.json b/packages/jsx2mp-loader/package.json index 04d91aec..84839087 100644 --- a/packages/jsx2mp-loader/package.json +++ b/packages/jsx2mp-loader/package.json @@ -20,8 +20,10 @@ "babel-plugin-danger-remove-unused-import": "^2.0.0", "babel-plugin-minify-dead-code-elimination-while-loop-fixed": "^0.3.0", "babel-plugin-transform-define": "^1.3.1", + "buffer-json": "^2.0.0", "chalk": "^2.4.2", "convert-source-map": "^1.6.0", + "crypto": "^1.0.1", "csso": "^3.5.1", "enhanced-resolve": "^4.1.1", "fs-extra": "^8.1.0", @@ -29,6 +31,7 @@ "less": "^4.0.0", "loader-utils": "^1.2.3", "miniapp-builder-shared": "^0.2.0", + "mkdirp": "^1.0.4", "pretty-data": "^0.40.0", "resolve": "^1.20.0", "sass": "^1.23.2", diff --git a/packages/jsx2mp-loader/src/app-loader.js b/packages/jsx2mp-loader/src/app-loader.js index 22c1a8ce..8492d5f7 100644 --- a/packages/jsx2mp-loader/src/app-loader.js +++ b/packages/jsx2mp-loader/src/app-loader.js @@ -87,6 +87,7 @@ module.exports = async function appLoader(content) { type: 'app', platform, rootDir, + resourcePath: this.resourcePath }; output(outputContent, rawContent, outputOption); diff --git a/packages/jsx2mp-loader/src/component-loader.js b/packages/jsx2mp-loader/src/component-loader.js index 5dc3e033..f8c87497 100644 --- a/packages/jsx2mp-loader/src/component-loader.js +++ b/packages/jsx2mp-loader/src/component-loader.js @@ -124,6 +124,7 @@ module.exports = async function componentLoader(content) { platform, isTypescriptFile: isTypescriptFile(this.resourcePath), rootDir, + resourcePath: this.resourcePath }; output(outputContent, content, outputOption); diff --git a/packages/jsx2mp-loader/src/output.js b/packages/jsx2mp-loader/src/output.js index c7fb7468..5d8c46bd 100644 --- a/packages/jsx2mp-loader/src/output.js +++ b/packages/jsx2mp-loader/src/output.js @@ -4,6 +4,7 @@ const { transformSync } = require('@babel/core'); const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); const { minify, minifyJS, minifyCSS, minifyXML } = require('./utils/minifyCode'); const addSourceMap = require('./utils/addSourceMap'); +const saveCache = require('./utils/useCache'); function transformCode(rawContent, mode, externalPlugins = [], externalPreset = []) { const presets = [].concat(externalPreset); @@ -54,9 +55,10 @@ function transformCode(rawContent, mode, externalPlugins = [], externalPreset = * @param {object} options */ function output(content, raw, options) { - const { mode, outputPath, externalPlugins = [], isTypescriptFile, platform, type, rootDir } = options; + const { mode, outputPath, externalPlugins = [], isTypescriptFile, platform, type, rootDir, resourcePath } = options; let { code, config, json, css, map, template, assets, importComponents = [], iconfontMap } = content; const isQuickApp = platform.type === QUICKAPP; + const collection = {}; if (isTypescriptFile) { externalPlugins.unshift(require('@babel/plugin-transform-typescript')); @@ -119,10 +121,12 @@ function output(content, raw, options) { } } writeFileWithDirCheck(outputPath.code, code, { rootDir }); + collection.code = code; } if (json) { writeFileWithDirCheck(outputPath.json, json, { rootDir, type: 'json' }); + collection.json = json; } if (template) { if (isQuickApp) { @@ -147,6 +151,7 @@ function output(content, raw, options) { } } writeFileWithDirCheck(outputPath.template, template, { rootDir }); + collection.template = template; } if (css) { if (isQuickApp) { @@ -165,9 +170,11 @@ function output(content, raw, options) { css = css.replace(/rpx/g, 'px'); } writeFileWithDirCheck(outputPath.css, css, { rootDir }); + collection.css = css; } if (config) { writeFileWithDirCheck(outputPath.config, config, { rootDir }); + collection.config = config; } // Write extra assets @@ -183,8 +190,11 @@ function output(content, raw, options) { } const assetsOutputPath = join(outputPath.assets, asset); writeFileWithDirCheck(assetsOutputPath, content, { rootDir }); + collection[`assets_${asset}`] = content; }); } + + saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, 'node_modules/.miniCache') }); } /** diff --git a/packages/jsx2mp-loader/src/page-loader.js b/packages/jsx2mp-loader/src/page-loader.js index 0ada3ba8..4627d3ba 100644 --- a/packages/jsx2mp-loader/src/page-loader.js +++ b/packages/jsx2mp-loader/src/page-loader.js @@ -130,6 +130,7 @@ module.exports = async function pageLoader(content) { platform, isTypescriptFile: isTypescriptFile(this.resourcePath), rootDir, + resourcePath: this.resourcePath }; output(outputContent, content, outputOption); diff --git a/packages/jsx2mp-loader/src/script-loader.js b/packages/jsx2mp-loader/src/script-loader.js index c20622d2..65d2865f 100644 --- a/packages/jsx2mp-loader/src/script-loader.js +++ b/packages/jsx2mp-loader/src/script-loader.js @@ -91,6 +91,7 @@ module.exports = function scriptLoader(content) { platform, isTypescriptFile: isTypescriptFile(this.resourcePath), rootDir, + resourcePath: this.resourcePath }; output(outputContent, null, outputOption); diff --git a/packages/jsx2mp-loader/src/utils/useCache.js b/packages/jsx2mp-loader/src/utils/useCache.js new file mode 100644 index 00000000..a8aa2979 --- /dev/null +++ b/packages/jsx2mp-loader/src/utils/useCache.js @@ -0,0 +1,82 @@ +const fs = require('fs-extra'); +const BJSON = require('buffer-json'); +const path = require('path'); +const mkdirp = require('mkdirp'); + +const saveCache = (content, { filePath, cacheDirectory }) => { + const stats = fs.statSync(filePath); + const mtime = stats.mtime.getTime(); + const cacheKey = cacheKeyFn({ + cacheDirectory, + filePath, + mtime, + }); + + write(cacheKey, content); +}; + +const getCache = ({ filePath, cacheDirectory }) => { + const stats = fs.statSync(filePath); + const mtime = stats.mtime.getTime(); + + const cacheKey = cacheKeyFn({ + cacheDirectory, + filePath, + mtime, + }); + + return read(cacheKey); +}; + +const directories = new Set(); + +function write(key, data, callback) { + const dirname = path.dirname(key); + const content = BJSON.stringify(data); + + if (directories.has(dirname)) { + // for performance skip creating directory + fs.writeFile(key, content, 'utf-8', callback); + } else { + mkdirp(dirname, (mkdirErr) => { + if (mkdirErr) { + callback(mkdirErr); + return; + } + + directories.add(dirname); + + fs.writeFile(key, content, 'utf-8', callback); + }); + } +} + +function read(key) { + try { + const content = fs.readFileSync(key, 'utf-8'); + const data = BJSON.parse(content); + return data; + } catch { + return null; + } +} + +function cacheKeyFn(options) { + const { cacheDirectory, filePath, mtime } = options; + const hash = digest(`${filePath}\n${mtime}`); + + return path.join(cacheDirectory, `${hash}.json`); +} + +function digest(str) { + return crypto.createHash('md5').update(str).digest('hex'); +} + +function compare(stats, dep) { + return stats.mtime.getTime() === dep.mtime; +} + +module.exports = { + saveCache, + getCache, +}; From 1ee5d1d9d099e547de2cc39ddc8469b0826326e9 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Mon, 15 Nov 2021 19:13:58 +0800 Subject: [PATCH 2/8] feat: add chache --- .../jsx2mp-loader/src/component-loader.js | 338 +++++++++++------- packages/jsx2mp-loader/src/output.js | 17 +- packages/jsx2mp-loader/src/script-loader.js | 18 +- packages/jsx2mp-loader/src/utils/useCache.js | 18 +- 4 files changed, 252 insertions(+), 139 deletions(-) diff --git a/packages/jsx2mp-loader/src/component-loader.js b/packages/jsx2mp-loader/src/component-loader.js index f8c87497..4088f203 100644 --- a/packages/jsx2mp-loader/src/component-loader.js +++ b/packages/jsx2mp-loader/src/component-loader.js @@ -1,15 +1,18 @@ const { existsSync, mkdirpSync } = require('fs-extra'); -const { relative, join, dirname, resolve } = require('path'); +const { relative, join, dirname, resolve, extname } = require('path'); const { getOptions } = require('loader-utils'); +const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); const chalk = require('chalk'); const cached = require('./cached'); const { removeExt, isFromTargetDirs, doubleBackslash, normalizeOutputFilePath, addRelativePathPrefix, getHighestPriorityPackage } = require('./utils/pathHelper'); const eliminateDeadCode = require('./utils/dce'); const { isTypescriptFile } = require('./utils/judgeModule'); +const { minify } = require('./utils/minifyCode'); const parse = require('./utils/parseRequest'); const processCSS = require('./styleProcessor'); -const { output } = require('./output'); +const { output, writeFileWithDirCheck } = require('./output'); +const { getCache } = require('./utils/useCache'); const ScriptLoader = require.resolve('./script-loader'); const MINIAPP_PLUGIN_COMPONENTS_REG = /^plugin\:\/\//; @@ -26,6 +29,7 @@ module.exports = async function componentLoader(content) { const resourcePath = this.resourcePath; const rootContext = this.rootContext; const absoluteConstantDir = constantDir.map(dir => join(rootContext, dir)); + const isQuickApp = platform.type === QUICKAPP; const sourcePath = join(rootContext, dirname(entryPath)); @@ -33,101 +37,12 @@ module.exports = async function componentLoader(content) { const distFileWithoutExt = removeExt(join(outputPath, relativeSourcePath), platform.type); const isFromConstantDir = cached(isFromTargetDirs(absoluteConstantDir)); + const outputPathCode = distFileWithoutExt + '.js'; + const outputPathJson = distFileWithoutExt + '.json'; + const outputPathCss = distFileWithoutExt + platform.extension.css; + const outputPathTemplate = distFileWithoutExt + platform.extension.xml; - const JSXCompilerPath = getHighestPriorityPackage('jsx-compiler', this.rootContext); - const compiler = require(JSXCompilerPath); - - const compilerOptions = Object.assign({}, compiler.baseOptions, { - resourcePath: this.resourcePath, - outputPath, - sourcePath, - type: 'component', - platform, - sourceFileName: this.resourcePath, - disableCopyNpm, - turnOffSourceMap, - aliasEntries, - virtualHost - }); - - let transformed; - try { - const rawContentAfterDCE = eliminateDeadCode(content); - transformed = compiler(rawContentAfterDCE, compilerOptions); - } catch (e) { - console.log(chalk.red(`\n[${platform.name}] Error occured when handling Component ${this.resourcePath}`)); - if (process.env.DEBUG === 'true') { - throw new Error(e); - } else { - const errMsg = e.node ? `${e.message}\nat ${this.resourcePath}` : `Unknown compile error! please check your code at ${this.resourcePath}`; - throw new Error(errMsg); - } - } - - const { style, assets } = await processCSS(transformed.cssFiles, sourcePath); - transformed.style = style; - transformed.assets = assets; - - const config = Object.assign({}, transformed.config); - if (Array.isArray(transformed.dependencies)) { - transformed.dependencies.forEach(dep => { - this.addDependency(dep); - }); - } - if (config.usingComponents) { - const usingComponents = {}; - Object.keys(config.usingComponents).forEach(key => { - const value = config.usingComponents[key]; - - if (/^c-/.test(key)) { - const result = MINIAPP_PLUGIN_COMPONENTS_REG.test(value) ? value : removeExt(addRelativePathPrefix(relative(dirname(this.resourcePath), value))); - usingComponents[key] = normalizeOutputFilePath(result); - } else { - usingComponents[key] = normalizeOutputFilePath(value); - } - }); - config.usingComponents = usingComponents; - } - - const distFileDir = dirname(distFileWithoutExt); - if (!existsSync(distFileDir)) mkdirpSync(distFileDir); - - // Only works when developing miniapp plugin, to declare the use of __app_css component - if (injectAppCssComponent) { - const appCssComponentPath = resolve(outputPath, '__app_css', 'index'); - const relativeAppCssComponentPath = relative(distFileDir, appCssComponentPath); - config.usingComponents = { - '__app_css': relativeAppCssComponentPath, - ...config.usingComponents - }; - } - - const outputContent = { - code: transformed.code, - map: transformed.map, - css: transformed.style || '', - json: config, - template: transformed.template, - assets: transformed.assets, - importComponents: transformed.importComponents, - iconfontMap: transformed.iconfontMap, - }; - const outputOption = { - outputPath: { - code: distFileWithoutExt + '.js', - json: distFileWithoutExt + '.json', - css: distFileWithoutExt + platform.extension.css, - template: distFileWithoutExt + platform.extension.xml, - assets: outputPath - }, - mode, - platform, - isTypescriptFile: isTypescriptFile(this.resourcePath), - rootDir, - resourcePath: this.resourcePath - }; - - output(outputContent, content, outputOption); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, 'node_modules/.miniCache') }); function isCustomComponent(name, usingComponents = {}) { const matchingPath = join(dirname(resourcePath), name); @@ -142,42 +57,219 @@ module.exports = async function componentLoader(content) { } return false; } + // console.log('cacheContentCode', cacheContent); + if (cacheContent) { + // console.log('writeFileWithDirCheck'); + if (cacheContent.code) { + writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir }); + } - const dependencies = []; - Object.keys(transformed.imported).forEach(name => { - if (isCustomComponent(name, transformed.usingComponents)) { - const componentPath = resolve(dirname(resourcePath), name); - dependencies.push({ - name: isFromConstantDir(componentPath) ? name : `${name}?role=component`, // Native miniapp component js file will loaded by script-loader - options: loaderOptions + if (cacheContent.json) { + writeFileWithDirCheck( outputPathJson, cacheContent.json, { rootDir, type: 'json' }); + } + + if (cacheContent.template) { + writeFileWithDirCheck( outputPathTemplate, cacheContent.template, { rootDir }); + } + + if (cacheContent.css) { + writeFileWithDirCheck( outputPathCss, cacheContent.css, { rootDir }); + } + + const assets = cacheContent.assets; + if (assets && Object.keys(assets).length) { + Object.keys(assets).forEach((asset) => { + const ext = extname(asset); + let content = assets[asset]; + if (content) { + if (isQuickApp) { + content = content.replace(/rpx/g, 'px'); + } + if (mode === 'build') { + content = minify(content, ext); + } + const assetsOutputPath = join(outputPath, asset); + console.log('assetsOutputPath', assetsOutputPath, asset); + writeFileWithDirCheck(assetsOutputPath, content, { rootDir }); + } }); - } else { - const importedArray = transformed.imported[name]; - let entirePush = false; - importedArray.forEach(importedContent => { - // Component library - if (importedContent.isFromComponentLibrary) { + } + + const dependencies = []; + if (cacheContent.imported) { + const imported = cacheContent.imported; + Object.keys(imported).forEach(name => { + if (isCustomComponent(name, cacheContent.usingComponents)) { + const componentPath = resolve(dirname(resourcePath), name); dependencies.push({ - name, - loader: ScriptLoader, - options: Object.assign({}, loaderOptions, { - importedComponent: importedContent.local - }) + name: isFromConstantDir(componentPath) ? name : `${name}?role=component`, // Native miniapp component js file will loaded by script-loader + options: loaderOptions }); } else { - if (!entirePush) { - dependencies.push({ name }); - entirePush = true; - } + const importedArray = imported[name]; + let entirePush = false; + importedArray.forEach(importedContent => { + // Component library + if (importedContent.isFromComponentLibrary) { + dependencies.push({ + name, + loader: ScriptLoader, + options: Object.assign({}, loaderOptions, { + importedComponent: importedContent.local + }) + }); + } else { + if (!entirePush) { + dependencies.push({ name }); + entirePush = true; + } + } + }); } }); } - }); - return [ - `/* Generated by JSX2MP ComponentLoader, sourceFile: ${this.resourcePath}. */`, - generateDependencies(dependencies), - ].join('\n'); + + return [ + `/* Generated by JSX2MP ComponentLoader, sourceFile: ${this.resourcePath}. */`, + generateDependencies(dependencies), + ].join('\n'); + } else { + const JSXCompilerPath = getHighestPriorityPackage('jsx-compiler', this.rootContext); + const compiler = require(JSXCompilerPath); + + const compilerOptions = Object.assign({}, compiler.baseOptions, { + resourcePath: this.resourcePath, + outputPath, + sourcePath, + type: 'component', + platform, + sourceFileName: this.resourcePath, + disableCopyNpm, + turnOffSourceMap, + aliasEntries, + virtualHost + }); + + let transformed; + try { + const rawContentAfterDCE = eliminateDeadCode(content); + transformed = compiler(rawContentAfterDCE, compilerOptions); + } catch (e) { + console.log(chalk.red(`\n[${platform.name}] Error occured when handling Component ${this.resourcePath}`)); + if (process.env.DEBUG === 'true') { + throw new Error(e); + } else { + const errMsg = e.node ? `${e.message}\nat ${this.resourcePath}` : `Unknown compile error! please check your code at ${this.resourcePath}`; + throw new Error(errMsg); + } + } + + const { style, assets } = await processCSS(transformed.cssFiles, sourcePath); + transformed.style = style; + transformed.assets = assets; + + const config = Object.assign({}, transformed.config); + if (Array.isArray(transformed.dependencies)) { + transformed.dependencies.forEach(dep => { + this.addDependency(dep); + }); + } + if (config.usingComponents) { + const usingComponents = {}; + Object.keys(config.usingComponents).forEach(key => { + const value = config.usingComponents[key]; + + if (/^c-/.test(key)) { + const result = MINIAPP_PLUGIN_COMPONENTS_REG.test(value) ? value : removeExt(addRelativePathPrefix(relative(dirname(this.resourcePath), value))); + usingComponents[key] = normalizeOutputFilePath(result); + } else { + usingComponents[key] = normalizeOutputFilePath(value); + } + }); + config.usingComponents = usingComponents; + } + + const distFileDir = dirname(distFileWithoutExt); + if (!existsSync(distFileDir)) mkdirpSync(distFileDir); + + // Only works when developing miniapp plugin, to declare the use of __app_css component + if (injectAppCssComponent) { + const appCssComponentPath = resolve(outputPath, '__app_css', 'index'); + const relativeAppCssComponentPath = relative(distFileDir, appCssComponentPath); + config.usingComponents = { + '__app_css': relativeAppCssComponentPath, + ...config.usingComponents + }; + } + + const outputContent = { + code: transformed.code, + map: transformed.map, + css: transformed.style || '', + json: config, + template: transformed.template, + assets: transformed.assets, + importComponents: transformed.importComponents, + iconfontMap: transformed.iconfontMap, + imported: transformed.imported, + usingComponents: transformed.usingComponents + }; + + const outputOption = { + outputPath: { + code: outputPathCode, + json: outputPathJson, + css: outputPathCss, + template: outputPathTemplate, + assets: outputPath + }, + mode, + platform, + isTypescriptFile: isTypescriptFile(this.resourcePath), + rootDir, + resourcePath: this.resourcePath + }; + + + output(outputContent, content, outputOption); + + const dependencies = []; + Object.keys(transformed.imported).forEach(name => { + if (isCustomComponent(name, transformed.usingComponents)) { + const componentPath = resolve(dirname(resourcePath), name); + dependencies.push({ + name: isFromConstantDir(componentPath) ? name : `${name}?role=component`, // Native miniapp component js file will loaded by script-loader + options: loaderOptions + }); + } else { + const importedArray = transformed.imported[name]; + let entirePush = false; + importedArray.forEach(importedContent => { + // Component library + if (importedContent.isFromComponentLibrary) { + dependencies.push({ + name, + loader: ScriptLoader, + options: Object.assign({}, loaderOptions, { + importedComponent: importedContent.local + }) + }); + } else { + if (!entirePush) { + dependencies.push({ name }); + entirePush = true; + } + } + }); + } + }); + + return [ + `/* Generated by JSX2MP ComponentLoader, sourceFile: ${this.resourcePath}. */`, + generateDependencies(dependencies), + ].join('\n'); + } }; function generateDependencies(dependencies) { diff --git a/packages/jsx2mp-loader/src/output.js b/packages/jsx2mp-loader/src/output.js index 5d8c46bd..0daefa67 100644 --- a/packages/jsx2mp-loader/src/output.js +++ b/packages/jsx2mp-loader/src/output.js @@ -4,7 +4,7 @@ const { transformSync } = require('@babel/core'); const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); const { minify, minifyJS, minifyCSS, minifyXML } = require('./utils/minifyCode'); const addSourceMap = require('./utils/addSourceMap'); -const saveCache = require('./utils/useCache'); +const { saveCache } = require('./utils/useCache'); function transformCode(rawContent, mode, externalPlugins = [], externalPreset = []) { const presets = [].concat(externalPreset); @@ -56,7 +56,7 @@ function transformCode(rawContent, mode, externalPlugins = [], externalPreset = */ function output(content, raw, options) { const { mode, outputPath, externalPlugins = [], isTypescriptFile, platform, type, rootDir, resourcePath } = options; - let { code, config, json, css, map, template, assets, importComponents = [], iconfontMap } = content; + let { code, config, json, css, map, template, assets, imported, usingComponents, importComponents = [], iconfontMap } = content; const isQuickApp = platform.type === QUICKAPP; const collection = {}; @@ -179,6 +179,7 @@ function output(content, raw, options) { // Write extra assets if (assets) { + collection.assets = assets; Object.keys(assets).forEach((asset) => { const ext = extname(asset); let content = assets[asset]; @@ -190,10 +191,17 @@ function output(content, raw, options) { } const assetsOutputPath = join(outputPath.assets, asset); writeFileWithDirCheck(assetsOutputPath, content, { rootDir }); - collection[`assets_${asset}`] = content; }); } + if (imported) { + collection.imported = imported; + } + + if (usingComponents) { + collection.usingComponents = usingComponents; + } + saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, 'node_modules/.miniCache') }); } @@ -256,5 +264,6 @@ function writeFileWithDirCheck(filePath, content, { type = 'file', rootDir }) { module.exports = { output, - transformCode + transformCode, + writeFileWithDirCheck }; diff --git a/packages/jsx2mp-loader/src/script-loader.js b/packages/jsx2mp-loader/src/script-loader.js index 65d2865f..30a872d5 100644 --- a/packages/jsx2mp-loader/src/script-loader.js +++ b/packages/jsx2mp-loader/src/script-loader.js @@ -9,7 +9,8 @@ const { removeExt, doubleBackslash, normalizeOutputFilePath, addRelativePathPref const { isNpmModule, isJSONFile, isTypescriptFile } = require('./utils/judgeModule'); const isMiniappComponent = require('./utils/isMiniappComponent'); const parse = require('./utils/parseRequest'); -const { output, transformCode } = require('./output'); +const { getCache } = require('./utils/useCache'); +const { output, transformCode, writeFileWithDirCheck } = require('./output'); const ScriptLoader = __filename; @@ -21,6 +22,7 @@ const MINIAPP_CONFIG_FIELD = 'miniappConfig'; // 2. .d.ts file in rax base components are useless const OMIT_FILE_EXTENSION_IN_OUTPUT = ['.json', '.ts']; +console.log('scriptLoader'); module.exports = function scriptLoader(content) { const query = parse(this.request); if (query.role) { @@ -70,9 +72,10 @@ module.exports = function scriptLoader(content) { let outputOption = {}; outputContent = { code: rawContent }; + const outputPathCode = removeExt(distSourcePath) + '.js'; outputOption = { outputPath: { - code: removeExt(distSourcePath) + '.js' + code: outputPathCode }, mode, externalPlugins: [ @@ -94,7 +97,15 @@ module.exports = function scriptLoader(content) { resourcePath: this.resourcePath }; - output(outputContent, null, outputOption); + + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, 'node_modules/.miniCache') }); + // console.log('cacheContentCode', cacheContent); + if (cacheContent && cacheContent.code) { + // console.log('writeFileWithDirCheck'); + writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir } ); + } else { + output(outputContent, null, outputOption); + } }; const outputDir = (source, target, { isThirdMiniappComponent = false, resourcePath } = {}) => { @@ -236,6 +247,7 @@ module.exports = function scriptLoader(content) { content ].join('\n'); } else { + // console.log('isFromNodeModule', isFromNodeModule); outputFile(rawContent); } } else if (isFromConstantDir(this.resourcePath) && isThirdMiniappComponent) { diff --git a/packages/jsx2mp-loader/src/utils/useCache.js b/packages/jsx2mp-loader/src/utils/useCache.js index a8aa2979..648e34cb 100644 --- a/packages/jsx2mp-loader/src/utils/useCache.js +++ b/packages/jsx2mp-loader/src/utils/useCache.js @@ -2,6 +2,7 @@ const fs = require('fs-extra'); const BJSON = require('buffer-json'); const path = require('path'); const mkdirp = require('mkdirp'); +const crypto = require('crypto'); const saveCache = (content, { filePath, cacheDirectory }) => { const stats = fs.statSync(filePath); @@ -33,21 +34,20 @@ const directories = new Set(); function write(key, data, callback) { const dirname = path.dirname(key); const content = BJSON.stringify(data); + // console.log('key', key, dirname); if (directories.has(dirname)) { // for performance skip creating directory fs.writeFile(key, content, 'utf-8', callback); } else { - mkdirp(dirname, (mkdirErr) => { - if (mkdirErr) { + mkdirp(dirname) + .catch((mkdirErr) => { callback(mkdirErr); - return; - } - - directories.add(dirname); - - fs.writeFile(key, content, 'utf-8', callback); - }); + }) + .then(() => { + directories.add(dirname); + fs.writeFile(key, content, 'utf-8', callback); + }); } } From 86ae993edebead42a4552cefc1cd01a5cf00d303 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Mon, 22 Nov 2021 20:58:41 +0800 Subject: [PATCH 3/8] chore: update --- .../src/setBaseConfig.js | 18 ++++++++++++++---- .../src/setComponentConfig.js | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/miniapp-compile-config/src/setBaseConfig.js b/packages/miniapp-compile-config/src/setBaseConfig.js index ea98e6e9..606e6194 100644 --- a/packages/miniapp-compile-config/src/setBaseConfig.js +++ b/packages/miniapp-compile-config/src/setBaseConfig.js @@ -76,7 +76,8 @@ module.exports = ( .options({ ...loaderParams, entryPath, - virtualHost + virtualHost, + rootDir }) .end() .use('platform') @@ -85,7 +86,10 @@ module.exports = ( .end() .use('script') .loader(ScriptLoader) - .options(loaderParams) + .options({ + ...loaderParams, + rootDir + }) .end(); chainConfig.module @@ -95,7 +99,10 @@ module.exports = ( .end() .use('script') .loader(ScriptLoader) - .options(loaderParams) + .options({ + ...loaderParams, + rootDir + }) .end(); chainConfig.module @@ -114,7 +121,10 @@ module.exports = ( .test(/\.json$/) .use('script-loader') .loader(ScriptLoader) - .options(loaderParams) + .options({ + ...loaderParams, + rootDir + }) .end() .use('json-loader') .loader(require.resolve('json-loader')); diff --git a/packages/miniapp-compile-config/src/setComponentConfig.js b/packages/miniapp-compile-config/src/setComponentConfig.js index a5eb68e2..5f9cb588 100644 --- a/packages/miniapp-compile-config/src/setComponentConfig.js +++ b/packages/miniapp-compile-config/src/setComponentConfig.js @@ -30,6 +30,7 @@ module.exports = ( disableCopyNpm, turnOffSourceMap, platform: platformInfo, + rootDir }; config.entryPoints.clear(); From e375fb1897b4ae97e9dffe401c47f277322949b5 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Mon, 22 Nov 2021 20:59:06 +0800 Subject: [PATCH 4/8] chore: update --- packages/jsx2mp-loader/src/app-loader.js | 2 + .../jsx2mp-loader/src/component-loader.js | 13 +- packages/jsx2mp-loader/src/output.js | 2 +- packages/jsx2mp-loader/src/page-loader.js | 355 +++++++++++------- packages/jsx2mp-loader/src/script-loader.js | 3 +- packages/jsx2mp-loader/src/utils/useCache.js | 2 + 6 files changed, 241 insertions(+), 136 deletions(-) diff --git a/packages/jsx2mp-loader/src/app-loader.js b/packages/jsx2mp-loader/src/app-loader.js index 8492d5f7..9f77afa7 100644 --- a/packages/jsx2mp-loader/src/app-loader.js +++ b/packages/jsx2mp-loader/src/app-loader.js @@ -23,6 +23,8 @@ function generateDependencies(dependencies) { } module.exports = async function appLoader(content) { + console.log('app-loader resourcePath', this.resourcePath); + const query = parse(this.request); // Only handle app role file if (query.role !== 'app') { diff --git a/packages/jsx2mp-loader/src/component-loader.js b/packages/jsx2mp-loader/src/component-loader.js index 4088f203..7103feba 100644 --- a/packages/jsx2mp-loader/src/component-loader.js +++ b/packages/jsx2mp-loader/src/component-loader.js @@ -1,4 +1,4 @@ -const { existsSync, mkdirpSync } = require('fs-extra'); +const { existsSync, mkdirpSync, pathExistsSync } = require('fs-extra'); const { relative, join, dirname, resolve, extname } = require('path'); const { getOptions } = require('loader-utils'); const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); @@ -19,11 +19,17 @@ const MINIAPP_PLUGIN_COMPONENTS_REG = /^plugin\:\/\//; module.exports = async function componentLoader(content) { const query = parse(this.request); + + if (this.resourcePath.includes('mods')) { + console.log('component', this.request, query); + } // Only handle component role file if (query.role !== 'component') { return content; } + // console.log('componentLoader123', content); + const loaderOptions = getOptions(this); const { rootDir, platform, entryPath, outputPath, constantDir, mode, disableCopyNpm, turnOffSourceMap, aliasEntries, injectAppCssComponent, virtualHost } = loaderOptions; const resourcePath = this.resourcePath; @@ -41,8 +47,8 @@ module.exports = async function componentLoader(content) { const outputPathJson = distFileWithoutExt + '.json'; const outputPathCss = distFileWithoutExt + platform.extension.css; const outputPathTemplate = distFileWithoutExt + platform.extension.xml; - - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, 'node_modules/.miniCache') }); + console.log('component', resourcePath); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); function isCustomComponent(name, usingComponents = {}) { const matchingPath = join(dirname(resourcePath), name); @@ -61,6 +67,7 @@ module.exports = async function componentLoader(content) { if (cacheContent) { // console.log('writeFileWithDirCheck'); if (cacheContent.code) { + console.log('outputPathCode', outputPathCode); writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir }); } diff --git a/packages/jsx2mp-loader/src/output.js b/packages/jsx2mp-loader/src/output.js index 0daefa67..bac102db 100644 --- a/packages/jsx2mp-loader/src/output.js +++ b/packages/jsx2mp-loader/src/output.js @@ -202,7 +202,7 @@ function output(content, raw, options) { collection.usingComponents = usingComponents; } - saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, 'node_modules/.miniCache') }); + saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); } /** diff --git a/packages/jsx2mp-loader/src/page-loader.js b/packages/jsx2mp-loader/src/page-loader.js index 4627d3ba..99623f15 100644 --- a/packages/jsx2mp-loader/src/page-loader.js +++ b/packages/jsx2mp-loader/src/page-loader.js @@ -1,18 +1,23 @@ -const { readFileSync, existsSync, mkdirpSync, readJSONSync } = require('fs-extra'); +const { readFileSync, existsSync, mkdirpSync, readJSONSync, extname } = require('fs-extra'); const { relative, join, dirname, resolve } = require('path'); +const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); const { getOptions } = require('loader-utils'); const chalk = require('chalk'); +const { minify } = require('./utils/minifyCode'); const cached = require('./cached'); const { removeExt, isFromTargetDirs, doubleBackslash, normalizeOutputFilePath, addRelativePathPrefix, getHighestPriorityPackage } = require('./utils/pathHelper'); const eliminateDeadCode = require('./utils/dce'); const processCSS = require('./styleProcessor'); -const { output } = require('./output'); const { isTypescriptFile } = require('./utils/judgeModule'); const parse = require('./utils/parseRequest'); +const { output, writeFileWithDirCheck } = require('./output'); +const { getCache } = require('./utils/useCache'); const ScriptLoader = require.resolve('./script-loader'); + const MINIAPP_PLUGIN_COMPONENTS_REG = /^plugin\:\/\//; +console.log('pageLoader'); module.exports = async function pageLoader(content) { const query = parse(this.request); // Only handle page role file @@ -24,6 +29,7 @@ module.exports = async function pageLoader(content) { const { rootDir, platform, entryPath, mode, disableCopyNpm, constantDir, turnOffSourceMap, outputPath, aliasEntries, injectAppCssComponent } = loaderOptions; const resourcePath = this.resourcePath; const rootContext = this.rootContext; + const isQuickApp = platform.type === QUICKAPP; const absoluteConstantDir = constantDir.map(dir => join(rootContext, dir)); const sourcePath = join(rootContext, dirname(entryPath)); @@ -31,155 +37,244 @@ module.exports = async function pageLoader(content) { const targetFilePath = join(outputPath, relativeSourcePath); const isFromConstantDir = cached(isFromTargetDirs(absoluteConstantDir)); - - const JSXCompilerPath = getHighestPriorityPackage('jsx-compiler', this.rootContext); - const compiler = require(JSXCompilerPath); - - const compilerOptions = Object.assign({}, compiler.baseOptions, { - resourcePath: this.resourcePath, - outputPath, - sourcePath, - type: 'page', - platform, - sourceFileName: this.resourcePath, - disableCopyNpm, - turnOffSourceMap, - aliasEntries - }); - const rawContentAfterDCE = eliminateDeadCode(content); - - let transformed; - try { - transformed = compiler(rawContentAfterDCE, compilerOptions); - } catch (e) { - console.log(chalk.red(`\n[${platform.name}] Error occured when handling Page ${this.resourcePath}`)); - if (process.env.DEBUG === 'true') { - throw new Error(e); - } else { - const errMsg = e.node ? `${e.message}\nat ${this.resourcePath}` : `Unknown compile error! please check your code at ${this.resourcePath}`; - throw new Error(errMsg); - } - } - - const { style, assets } = await processCSS(transformed.cssFiles, sourcePath); - transformed.style = style; - transformed.assets = assets; - - const pageDistDir = dirname(targetFilePath); - if (!existsSync(pageDistDir)) mkdirpSync(pageDistDir); - const distFileWithoutExt = removeExt(join(outputPath, relativeSourcePath), platform.type); + const outputPathCode = distFileWithoutExt + '.js'; const pageConfigPath = distFileWithoutExt + '.json'; - let config = { - ...transformed.config - }; - if (existsSync(pageConfigPath)) { - const pageConfig = readJSONSync(pageConfigPath); - delete pageConfig.usingComponents; - Object.assign(config, pageConfig); - } - if (Array.isArray(transformed.dependencies)) { - transformed.dependencies.forEach(dep => { - this.addDependency(dep); - }); - } - - if (config.usingComponents) { - const usingComponents = {}; - Object.keys(config.usingComponents).forEach(key => { - const value = config.usingComponents[key]; - if (/^c-/.test(key)) { - const result = MINIAPP_PLUGIN_COMPONENTS_REG.test(value) ? value : removeExt(addRelativePathPrefix(relative(dirname(this.resourcePath), value))); - usingComponents[key] = normalizeOutputFilePath(result); - } else { - usingComponents[key] = normalizeOutputFilePath(value); - } - }); - config.usingComponents = usingComponents; - } + const outputPathJson = pageConfigPath; + const outputPathCss = distFileWithoutExt + platform.extension.css; + const outputPathTemplate = distFileWithoutExt + platform.extension.xml; - // Only works when developing miniapp plugin, to declare the use of __app_css component - if (injectAppCssComponent) { - const appCssComponentPath = resolve(outputPath, '__app_css', 'index'); - const relativeAppCssComponentPath = relative(pageDistDir, appCssComponentPath); - config.usingComponents = { - '__app_css': relativeAppCssComponentPath, - ...config.usingComponents - }; - } + // console.log('query', resourcePath); - const outputContent = { - code: transformed.code, - map: transformed.map, - css: transformed.style || '', - json: config, - template: transformed.template, - assets: transformed.assets, - importComponents: transformed.importComponents, - iconfontMap: transformed.iconfontMap, - }; - const outputOption = { - outputPath: { - code: distFileWithoutExt + '.js', - json: pageConfigPath, - css: distFileWithoutExt + platform.extension.css, - template: distFileWithoutExt + platform.extension.xml, - assets: outputPath - }, - mode, - platform, - isTypescriptFile: isTypescriptFile(this.resourcePath), - rootDir, - resourcePath: this.resourcePath - }; - - output(outputContent, content, outputOption); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); function isCustomComponent(name, usingComponents = {}) { const matchingPath = join(dirname(resourcePath), name); for (let key in usingComponents) { - if (usingComponents.hasOwnProperty(key) - && usingComponents[key].indexOf(matchingPath) === 0) { + if ( + usingComponents.hasOwnProperty(key) + && usingComponents[key] + && usingComponents[key].indexOf(matchingPath) === 0 + ) { return true; } } return false; } - const dependencies = []; - Object.keys(transformed.imported).forEach(name => { - if (isCustomComponent(name, transformed.usingComponents)) { - const componentPath = resolve(dirname(resourcePath), name); - dependencies.push({ - name: isFromConstantDir(componentPath) ? name : `${name}?role=component`, // Native miniapp component js file will be loaded by script-loader - options: loaderOptions + if (cacheContent) { + // console.log('writeFileWithDirCheck'); + if (cacheContent.code) { + writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir }); + } + + if (cacheContent.json) { + writeFileWithDirCheck( outputPathJson, cacheContent.json, { rootDir, type: 'json' }); + } + + if (cacheContent.template) { + writeFileWithDirCheck( outputPathTemplate, cacheContent.template, { rootDir }); + } + + if (cacheContent.css) { + writeFileWithDirCheck( outputPathCss, cacheContent.css, { rootDir }); + } + + const assets = cacheContent.assets; + if (assets && Object.keys(assets).length) { + Object.keys(assets).forEach((asset) => { + const ext = extname(asset); + let content = assets[asset]; + if (content) { + if (isQuickApp) { + content = content.replace(/rpx/g, 'px'); + } + if (mode === 'build') { + content = minify(content, ext); + } + const assetsOutputPath = join(outputPath, asset); + console.log('assetsOutputPath', assetsOutputPath, asset); + writeFileWithDirCheck(assetsOutputPath, content, { rootDir }); + } }); - } else { - const importedArray = transformed.imported[name]; - let entirePush = false; - importedArray.forEach(importedContent => { - // Component library - if (importedContent.isFromComponentLibrary) { + } + + const dependencies = []; + if (cacheContent.imported) { + const imported = cacheContent.imported; + Object.keys(imported).forEach(name => { + if (isCustomComponent(name, cacheContent.usingComponents)) { + const componentPath = resolve(dirname(resourcePath), name); dependencies.push({ - name, - loader: ScriptLoader, - options: Object.assign({}, loaderOptions, { - importedComponent: importedContent.local - }) + name: isFromConstantDir(componentPath) ? name : `${name}?role=component`, // Native miniapp component js file will loaded by script-loader + options: loaderOptions }); } else { - if (!entirePush) { - dependencies.push({ name }); - entirePush = true; - } + const importedArray = imported[name]; + let entirePush = false; + importedArray.forEach(importedContent => { + // Component library + if (importedContent.isFromComponentLibrary) { + dependencies.push({ + name, + loader: ScriptLoader, + options: Object.assign({}, loaderOptions, { + importedComponent: importedContent.local + }) + }); + } else { + if (!entirePush) { + dependencies.push({ name }); + entirePush = true; + } + } + }); } }); } - }); - return [ - `/* Generated by JSX2MP PageLoader, sourceFile: ${this.resourcePath}. */`, - generateDependencies(dependencies), - ].join('\n'); + + + return [ + `/* Generated by JSX2MP ComponentLoader, sourceFile: ${this.resourcePath}. */`, + generateDependencies(dependencies), + ].join('\n'); + } else { + const JSXCompilerPath = getHighestPriorityPackage('jsx-compiler', this.rootContext); + const compiler = require(JSXCompilerPath); + + const compilerOptions = Object.assign({}, compiler.baseOptions, { + resourcePath: this.resourcePath, + outputPath, + sourcePath, + type: 'page', + platform, + sourceFileName: this.resourcePath, + disableCopyNpm, + turnOffSourceMap, + aliasEntries + }); + const rawContentAfterDCE = eliminateDeadCode(content); + + let transformed; + try { + transformed = compiler(rawContentAfterDCE, compilerOptions); + } catch (e) { + console.log(chalk.red(`\n[${platform.name}] Error occured when handling Page ${this.resourcePath}`)); + if (process.env.DEBUG === 'true') { + throw new Error(e); + } else { + const errMsg = e.node ? `${e.message}\nat ${this.resourcePath}` : `Unknown compile error! please check your code at ${this.resourcePath}`; + throw new Error(errMsg); + } + } + + const { style, assets } = await processCSS(transformed.cssFiles, sourcePath); + transformed.style = style; + transformed.assets = assets; + + const pageDistDir = dirname(targetFilePath); + if (!existsSync(pageDistDir)) mkdirpSync(pageDistDir); + + let config = { + ...transformed.config + }; + if (existsSync(pageConfigPath)) { + const pageConfig = readJSONSync(pageConfigPath); + delete pageConfig.usingComponents; + Object.assign(config, pageConfig); + } + if (Array.isArray(transformed.dependencies)) { + transformed.dependencies.forEach(dep => { + this.addDependency(dep); + }); + } + + if (config.usingComponents) { + const usingComponents = {}; + Object.keys(config.usingComponents).forEach(key => { + const value = config.usingComponents[key]; + if (/^c-/.test(key)) { + const result = MINIAPP_PLUGIN_COMPONENTS_REG.test(value) ? value : removeExt(addRelativePathPrefix(relative(dirname(this.resourcePath), value))); + usingComponents[key] = normalizeOutputFilePath(result); + } else { + usingComponents[key] = normalizeOutputFilePath(value); + } + }); + config.usingComponents = usingComponents; + } + + // Only works when developing miniapp plugin, to declare the use of __app_css component + if (injectAppCssComponent) { + const appCssComponentPath = resolve(outputPath, '__app_css', 'index'); + const relativeAppCssComponentPath = relative(pageDistDir, appCssComponentPath); + config.usingComponents = { + '__app_css': relativeAppCssComponentPath, + ...config.usingComponents + }; + } + + const outputContent = { + code: transformed.code, + map: transformed.map, + css: transformed.style || '', + json: config, + template: transformed.template, + assets: transformed.assets, + importComponents: transformed.importComponents, + iconfontMap: transformed.iconfontMap, + }; + const outputOption = { + outputPath: { + code: distFileWithoutExt + '.js', + json: pageConfigPath, + css: distFileWithoutExt + platform.extension.css, + template: distFileWithoutExt + platform.extension.xml, + assets: outputPath + }, + mode, + platform, + isTypescriptFile: isTypescriptFile(this.resourcePath), + rootDir, + resourcePath: this.resourcePath + }; + + output(outputContent, content, outputOption); + + const dependencies = []; + Object.keys(transformed.imported).forEach(name => { + if (isCustomComponent(name, transformed.usingComponents)) { + const componentPath = resolve(dirname(resourcePath), name); + dependencies.push({ + name: isFromConstantDir(componentPath) ? name : `${name}?role=component`, // Native miniapp component js file will be loaded by script-loader + options: loaderOptions + }); + } else { + const importedArray = transformed.imported[name]; + let entirePush = false; + importedArray.forEach(importedContent => { + // Component library + if (importedContent.isFromComponentLibrary) { + dependencies.push({ + name, + loader: ScriptLoader, + options: Object.assign({}, loaderOptions, { + importedComponent: importedContent.local + }) + }); + } else { + if (!entirePush) { + dependencies.push({ name }); + entirePush = true; + } + } + }); + } + }); + return [ + `/* Generated by JSX2MP PageLoader, sourceFile: ${this.resourcePath}. */`, + generateDependencies(dependencies), + ].join('\n'); + } }; function createImportStatement(req) { diff --git a/packages/jsx2mp-loader/src/script-loader.js b/packages/jsx2mp-loader/src/script-loader.js index 30a872d5..1caf3da6 100644 --- a/packages/jsx2mp-loader/src/script-loader.js +++ b/packages/jsx2mp-loader/src/script-loader.js @@ -97,8 +97,7 @@ module.exports = function scriptLoader(content) { resourcePath: this.resourcePath }; - - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, 'node_modules/.miniCache') }); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); // console.log('cacheContentCode', cacheContent); if (cacheContent && cacheContent.code) { // console.log('writeFileWithDirCheck'); diff --git a/packages/jsx2mp-loader/src/utils/useCache.js b/packages/jsx2mp-loader/src/utils/useCache.js index 648e34cb..37aa5265 100644 --- a/packages/jsx2mp-loader/src/utils/useCache.js +++ b/packages/jsx2mp-loader/src/utils/useCache.js @@ -17,6 +17,8 @@ const saveCache = (content, { filePath, cacheDirectory }) => { }; const getCache = ({ filePath, cacheDirectory }) => { + if (!fs.pathExistsSync(cacheDirectory)) return null; + const stats = fs.statSync(filePath); const mtime = stats.mtime.getTime(); From ca35cc1c665b7d64e0f36446637115c6750c0d10 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Mon, 22 Nov 2021 21:33:11 +0800 Subject: [PATCH 5/8] fix: pageloader --- packages/jsx2mp-loader/src/app-loader.js | 2 -- packages/jsx2mp-loader/src/component-loader.js | 10 +--------- packages/jsx2mp-loader/src/output.js | 2 +- packages/jsx2mp-loader/src/page-loader.js | 6 ++++-- packages/jsx2mp-loader/src/script-loader.js | 2 +- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/packages/jsx2mp-loader/src/app-loader.js b/packages/jsx2mp-loader/src/app-loader.js index 9f77afa7..8492d5f7 100644 --- a/packages/jsx2mp-loader/src/app-loader.js +++ b/packages/jsx2mp-loader/src/app-loader.js @@ -23,8 +23,6 @@ function generateDependencies(dependencies) { } module.exports = async function appLoader(content) { - console.log('app-loader resourcePath', this.resourcePath); - const query = parse(this.request); // Only handle app role file if (query.role !== 'app') { diff --git a/packages/jsx2mp-loader/src/component-loader.js b/packages/jsx2mp-loader/src/component-loader.js index 7103feba..70c0d132 100644 --- a/packages/jsx2mp-loader/src/component-loader.js +++ b/packages/jsx2mp-loader/src/component-loader.js @@ -19,17 +19,11 @@ const MINIAPP_PLUGIN_COMPONENTS_REG = /^plugin\:\/\//; module.exports = async function componentLoader(content) { const query = parse(this.request); - - if (this.resourcePath.includes('mods')) { - console.log('component', this.request, query); - } // Only handle component role file if (query.role !== 'component') { return content; } - // console.log('componentLoader123', content); - const loaderOptions = getOptions(this); const { rootDir, platform, entryPath, outputPath, constantDir, mode, disableCopyNpm, turnOffSourceMap, aliasEntries, injectAppCssComponent, virtualHost } = loaderOptions; const resourcePath = this.resourcePath; @@ -47,8 +41,7 @@ module.exports = async function componentLoader(content) { const outputPathJson = distFileWithoutExt + '.json'; const outputPathCss = distFileWithoutExt + platform.extension.css; const outputPathTemplate = distFileWithoutExt + platform.extension.xml; - console.log('component', resourcePath); - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); function isCustomComponent(name, usingComponents = {}) { const matchingPath = join(dirname(resourcePath), name); @@ -67,7 +60,6 @@ module.exports = async function componentLoader(content) { if (cacheContent) { // console.log('writeFileWithDirCheck'); if (cacheContent.code) { - console.log('outputPathCode', outputPathCode); writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir }); } diff --git a/packages/jsx2mp-loader/src/output.js b/packages/jsx2mp-loader/src/output.js index bac102db..80a0531f 100644 --- a/packages/jsx2mp-loader/src/output.js +++ b/packages/jsx2mp-loader/src/output.js @@ -202,7 +202,7 @@ function output(content, raw, options) { collection.usingComponents = usingComponents; } - saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); + saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); } /** diff --git a/packages/jsx2mp-loader/src/page-loader.js b/packages/jsx2mp-loader/src/page-loader.js index 99623f15..1acd8912 100644 --- a/packages/jsx2mp-loader/src/page-loader.js +++ b/packages/jsx2mp-loader/src/page-loader.js @@ -17,7 +17,6 @@ const ScriptLoader = require.resolve('./script-loader'); const MINIAPP_PLUGIN_COMPONENTS_REG = /^plugin\:\/\//; -console.log('pageLoader'); module.exports = async function pageLoader(content) { const query = parse(this.request); // Only handle page role file @@ -46,7 +45,7 @@ module.exports = async function pageLoader(content) { // console.log('query', resourcePath); - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); function isCustomComponent(name, usingComponents = {}) { const matchingPath = join(dirname(resourcePath), name); @@ -222,6 +221,9 @@ module.exports = async function pageLoader(content) { assets: transformed.assets, importComponents: transformed.importComponents, iconfontMap: transformed.iconfontMap, + imported: transformed.imported, + usingComponents: transformed.usingComponents + }; const outputOption = { outputPath: { diff --git a/packages/jsx2mp-loader/src/script-loader.js b/packages/jsx2mp-loader/src/script-loader.js index 1caf3da6..0fc236eb 100644 --- a/packages/jsx2mp-loader/src/script-loader.js +++ b/packages/jsx2mp-loader/src/script-loader.js @@ -97,7 +97,7 @@ module.exports = function scriptLoader(content) { resourcePath: this.resourcePath }; - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `node_modules/.miniCache/${mode}`) }); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); // console.log('cacheContentCode', cacheContent); if (cacheContent && cacheContent.code) { // console.log('writeFileWithDirCheck'); From 611bedd285261cab8f4e823bb033d53ffb42d3e8 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Thu, 25 Nov 2021 09:49:53 +0800 Subject: [PATCH 6/8] chore: nouse dep remove --- packages/jsx2mp-loader/src/component-loader.js | 2 +- packages/jsx2mp-loader/src/page-loader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jsx2mp-loader/src/component-loader.js b/packages/jsx2mp-loader/src/component-loader.js index a3fc141e..7f7e1f11 100644 --- a/packages/jsx2mp-loader/src/component-loader.js +++ b/packages/jsx2mp-loader/src/component-loader.js @@ -1,4 +1,4 @@ -const { existsSync, mkdirpSync, pathExistsSync } = require('fs-extra'); +const { existsSync, mkdirpSync } = require('fs-extra'); const { relative, join, dirname, resolve, extname } = require('path'); const { getOptions } = require('loader-utils'); const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); diff --git a/packages/jsx2mp-loader/src/page-loader.js b/packages/jsx2mp-loader/src/page-loader.js index 0362febb..b5618f7b 100644 --- a/packages/jsx2mp-loader/src/page-loader.js +++ b/packages/jsx2mp-loader/src/page-loader.js @@ -1,4 +1,4 @@ -const { readFileSync, existsSync, mkdirpSync, readJSONSync, extname } = require('fs-extra'); +const { existsSync, mkdirpSync, readJSONSync, extname } = require('fs-extra'); const { relative, join, dirname, resolve } = require('path'); const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); const { getOptions } = require('loader-utils'); From 5c93b89e8f87b4950c4807101fd7ab5a47fe6f60 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Tue, 11 Jan 2022 22:00:37 +0800 Subject: [PATCH 7/8] feat: add cache params --- packages/miniapp-compile-config/src/setAppConfig.js | 4 +++- packages/miniapp-compile-config/src/setComponentConfig.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/miniapp-compile-config/src/setAppConfig.js b/packages/miniapp-compile-config/src/setAppConfig.js index 329858e8..cdcc471d 100644 --- a/packages/miniapp-compile-config/src/setAppConfig.js +++ b/packages/miniapp-compile-config/src/setAppConfig.js @@ -23,7 +23,8 @@ module.exports = ( disableCopyNpm = false, turnOffSourceMap = false, constantDir = [], - subPackages = false + subPackages = false, + cache, } = userConfig; const { rootDir, command } = context; const mode = command; @@ -47,6 +48,7 @@ module.exports = ( const loaderParams = { mode, + cache, entryPath, outputPath, disableCopyNpm, diff --git a/packages/miniapp-compile-config/src/setComponentConfig.js b/packages/miniapp-compile-config/src/setComponentConfig.js index 5f9cb588..d5b8056c 100644 --- a/packages/miniapp-compile-config/src/setComponentConfig.js +++ b/packages/miniapp-compile-config/src/setComponentConfig.js @@ -11,7 +11,8 @@ module.exports = ( const platformInfo = platformMap[target]; const { turnOffSourceMap = false, - constantDir = [] + constantDir = [], + cache } = userConfig; const { rootDir, command } = context; @@ -25,6 +26,7 @@ module.exports = ( const loaderParams = { mode: command, + cache, entryPath, outputPath, disableCopyNpm, From 0c3a7970c1697b71180044a41e21fe0147b5cde1 Mon Sep 17 00:00:00 2001 From: "renyou.hdd" Date: Tue, 11 Jan 2022 22:09:46 +0800 Subject: [PATCH 8/8] feat: add params cache --- packages/jsx2mp-loader/src/component-loader.js | 18 +++++++++--------- packages/jsx2mp-loader/src/output.js | 10 +++++++--- packages/jsx2mp-loader/src/page-loader.js | 12 +++++++----- packages/jsx2mp-loader/src/script-loader.js | 15 ++++++++------- packages/jsx2mp-loader/src/utils/useCache.js | 6 +++++- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/packages/jsx2mp-loader/src/component-loader.js b/packages/jsx2mp-loader/src/component-loader.js index 7f7e1f11..4b46c569 100644 --- a/packages/jsx2mp-loader/src/component-loader.js +++ b/packages/jsx2mp-loader/src/component-loader.js @@ -12,7 +12,7 @@ const parse = require('./utils/parseRequest'); const processCSS = require('./styleProcessor'); const { output, writeFileWithDirCheck } = require('./output'); -const { getCache } = require('./utils/useCache'); +const { getCache, getCacheDirName } = require('./utils/useCache'); const ScriptLoader = require.resolve('./script-loader'); const MINIAPP_PLUGIN_COMPONENTS_REG = /^plugin\:\/\//; @@ -25,7 +25,7 @@ module.exports = async function componentLoader(content) { } const loaderOptions = getOptions(this); - const { rootDir, platform, entryPath, outputPath, constantDir, mode, disableCopyNpm, turnOffSourceMap, aliasEntries, injectAppCssComponent, virtualHost } = loaderOptions; + const { rootDir, platform, entryPath, outputPath, constantDir, mode, disableCopyNpm, turnOffSourceMap, aliasEntries, injectAppCssComponent, virtualHost, cache } = loaderOptions; const resourcePath = this.resourcePath; const rootContext = this.rootContext; const absoluteConstantDir = constantDir.map(dir => join(rootContext, dir)); @@ -41,7 +41,9 @@ module.exports = async function componentLoader(content) { const outputPathJson = distFileWithoutExt + '.json'; const outputPathCss = distFileWithoutExt + platform.extension.css; const outputPathTemplate = distFileWithoutExt + platform.extension.xml; - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); + + const cacheDirectory = getCacheDirName({ config: cache, mode }); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, cacheDirectory) }); function isCustomComponent(name, usingComponents = {}) { const matchingPath = join(dirname(resourcePath), name); @@ -56,9 +58,9 @@ module.exports = async function componentLoader(content) { } return false; } - // console.log('cacheContentCode', cacheContent); - if (cacheContent) { - // console.log('writeFileWithDirCheck'); + + // cache and cacheContent exsit + if (cache && cacheContent) { if (cacheContent.code) { writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir }); } @@ -88,7 +90,6 @@ module.exports = async function componentLoader(content) { content = minify(content, ext); } const assetsOutputPath = join(outputPath, asset); - console.log('assetsOutputPath', assetsOutputPath, asset); writeFileWithDirCheck(assetsOutputPath, content, { rootDir }); } }); @@ -127,8 +128,6 @@ module.exports = async function componentLoader(content) { } }); } - - return [ `/* Generated by JSX2MP ComponentLoader, sourceFile: ${this.resourcePath}. */`, generateDependencies(dependencies), @@ -223,6 +222,7 @@ module.exports = async function componentLoader(content) { template: outputPathTemplate, assets: outputPath }, + cache, mode, platform, isTypescriptFile: isTypescriptFile(this.resourcePath), diff --git a/packages/jsx2mp-loader/src/output.js b/packages/jsx2mp-loader/src/output.js index 80a0531f..db4b7c20 100644 --- a/packages/jsx2mp-loader/src/output.js +++ b/packages/jsx2mp-loader/src/output.js @@ -4,7 +4,7 @@ const { transformSync } = require('@babel/core'); const { constants: { QUICKAPP }} = require('miniapp-builder-shared'); const { minify, minifyJS, minifyCSS, minifyXML } = require('./utils/minifyCode'); const addSourceMap = require('./utils/addSourceMap'); -const { saveCache } = require('./utils/useCache'); +const { saveCache, getCacheDirName } = require('./utils/useCache'); function transformCode(rawContent, mode, externalPlugins = [], externalPreset = []) { const presets = [].concat(externalPreset); @@ -55,7 +55,7 @@ function transformCode(rawContent, mode, externalPlugins = [], externalPreset = * @param {object} options */ function output(content, raw, options) { - const { mode, outputPath, externalPlugins = [], isTypescriptFile, platform, type, rootDir, resourcePath } = options; + const { mode, outputPath, externalPlugins = [], isTypescriptFile, platform, type, rootDir, cache, resourcePath } = options; let { code, config, json, css, map, template, assets, imported, usingComponents, importComponents = [], iconfontMap } = content; const isQuickApp = platform.type === QUICKAPP; const collection = {}; @@ -202,7 +202,11 @@ function output(content, raw, options) { collection.usingComponents = usingComponents; } - saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); + // save cache + if (cache) { + const cacheDirectory = getCacheDirName({ config: cache, mode}); + saveCache(collection, { filePath: resourcePath, cacheDirectory: join(rootDir, cacheDirectory) }); + } } /** diff --git a/packages/jsx2mp-loader/src/page-loader.js b/packages/jsx2mp-loader/src/page-loader.js index b5618f7b..ca648503 100644 --- a/packages/jsx2mp-loader/src/page-loader.js +++ b/packages/jsx2mp-loader/src/page-loader.js @@ -11,7 +11,7 @@ const processCSS = require('./styleProcessor'); const { isTypescriptFile } = require('./utils/judgeModule'); const parse = require('./utils/parseRequest'); const { output, writeFileWithDirCheck } = require('./output'); -const { getCache } = require('./utils/useCache'); +const { getCache, getCacheDirName } = require('./utils/useCache'); const ScriptLoader = require.resolve('./script-loader'); @@ -25,7 +25,7 @@ module.exports = async function pageLoader(content) { } const loaderOptions = getOptions(this); - const { rootDir, platform, entryPath, mode, disableCopyNpm, constantDir, turnOffSourceMap, outputPath, aliasEntries, injectAppCssComponent } = loaderOptions; + const { rootDir, platform, entryPath, mode, disableCopyNpm, constantDir, turnOffSourceMap, outputPath, aliasEntries, injectAppCssComponent, cache } = loaderOptions; const resourcePath = this.resourcePath; const rootContext = this.rootContext; const isQuickApp = platform.type === QUICKAPP; @@ -43,7 +43,8 @@ module.exports = async function pageLoader(content) { const outputPathCss = distFileWithoutExt + platform.extension.css; const outputPathTemplate = distFileWithoutExt + platform.extension.xml; - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); + const cacheDirectory = getCacheDirName({ config: cache, mode }); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, cacheDirectory) }); function isCustomComponent(name, usingComponents = {}) { const matchingPath = join(dirname(resourcePath), name); @@ -59,8 +60,8 @@ module.exports = async function pageLoader(content) { return false; } - if (cacheContent) { - // console.log('writeFileWithDirCheck'); + // cache and cacheContent exsit + if (cache && cacheContent) { if (cacheContent.code) { writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir }); } @@ -231,6 +232,7 @@ module.exports = async function pageLoader(content) { template: distFileWithoutExt + platform.extension.xml, assets: outputPath }, + cache, mode, platform, isTypescriptFile: isTypescriptFile(this.resourcePath), diff --git a/packages/jsx2mp-loader/src/script-loader.js b/packages/jsx2mp-loader/src/script-loader.js index 0fc236eb..b131cfba 100644 --- a/packages/jsx2mp-loader/src/script-loader.js +++ b/packages/jsx2mp-loader/src/script-loader.js @@ -9,7 +9,7 @@ const { removeExt, doubleBackslash, normalizeOutputFilePath, addRelativePathPref const { isNpmModule, isJSONFile, isTypescriptFile } = require('./utils/judgeModule'); const isMiniappComponent = require('./utils/isMiniappComponent'); const parse = require('./utils/parseRequest'); -const { getCache } = require('./utils/useCache'); +const { getCache, getCacheDirName } = require('./utils/useCache'); const { output, transformCode, writeFileWithDirCheck } = require('./output'); const ScriptLoader = __filename; @@ -22,7 +22,6 @@ const MINIAPP_CONFIG_FIELD = 'miniappConfig'; // 2. .d.ts file in rax base components are useless const OMIT_FILE_EXTENSION_IN_OUTPUT = ['.json', '.ts']; -console.log('scriptLoader'); module.exports = function scriptLoader(content) { const query = parse(this.request); if (query.role) { @@ -30,7 +29,7 @@ module.exports = function scriptLoader(content) { } const loaderOptions = getOptions(this); - const { rootDir, disableCopyNpm, outputPath, mode, entryPath, platform, importedComponent = '', isRelativeMiniappComponent = false, aliasEntries, constantDir } = loaderOptions; + const { rootDir, disableCopyNpm, outputPath, mode, entryPath, platform, importedComponent = '', isRelativeMiniappComponent = false, aliasEntries, constantDir, cache } = loaderOptions; const rootContext = this.rootContext; const isJSON = isJSONFile(this.resourcePath); const isAppJSon = this.resourcePath === join(rootContext, 'src', 'app.json'); @@ -45,6 +44,7 @@ module.exports = function scriptLoader(content) { return path.indexOf(rootNodeModulePath) === 0; }); + // console.log('script cache', this.resourcePath); const isFromConstantDir = cached(isFromTargetDirs(constantDir)); const getNpmFolderName = cached(function getNpmName(relativeNpmPath) { @@ -77,6 +77,7 @@ module.exports = function scriptLoader(content) { outputPath: { code: outputPathCode }, + cache, mode, externalPlugins: [ [ @@ -97,10 +98,10 @@ module.exports = function scriptLoader(content) { resourcePath: this.resourcePath }; - const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, `.miniCache/${mode}`) }); - // console.log('cacheContentCode', cacheContent); - if (cacheContent && cacheContent.code) { - // console.log('writeFileWithDirCheck'); + const cacheDirectory = getCacheDirName({ config: cache, mode }); + const cacheContent = getCache({ filePath: this.resourcePath, cacheDirectory: join(rootDir, cacheDirectory) }); + + if (cache && cacheContent && cacheContent.code) { writeFileWithDirCheck( outputPathCode, cacheContent.code, { rootDir } ); } else { output(outputContent, null, outputOption); diff --git a/packages/jsx2mp-loader/src/utils/useCache.js b/packages/jsx2mp-loader/src/utils/useCache.js index 37aa5265..4b2d967d 100644 --- a/packages/jsx2mp-loader/src/utils/useCache.js +++ b/packages/jsx2mp-loader/src/utils/useCache.js @@ -31,12 +31,15 @@ const getCache = ({ filePath, cacheDirectory }) => { return read(cacheKey); }; +const getCacheDirName = ({ config, mode }) => { + return `${typeof config === 'object' && config.cacheDirectory || '.miniCache'}/${mode}`; +}; + const directories = new Set(); function write(key, data, callback) { const dirname = path.dirname(key); const content = BJSON.stringify(data); - // console.log('key', key, dirname); if (directories.has(dirname)) { // for performance skip creating directory @@ -81,4 +84,5 @@ function compare(stats, dep) { module.exports = { saveCache, getCache, + getCacheDirName };