fix: refactor error handling (#6286)

* fix: refactor error handling

* fix: logger

* fix: sourcemap

* fix: test case

* fix: test

* fix: add brief error message

* fix: changelog and lint
This commit is contained in:
ClarkXia 2023-06-08 18:12:12 +08:00 committed by GitHub
parent abdd49de8d
commit c70c77379d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 347 additions and 348 deletions

View File

@ -0,0 +1,5 @@
---
'@ice/app': patch
---
fix: refactor error handling

View File

@ -0,0 +1,5 @@
---
'@ice/webpack-config': patch
---
fix: refactor error handling

View File

@ -0,0 +1,5 @@
---
'@ice/bundles': patch
---
fix: bump webpack(5.84.1) and webpack-dev-server(4.15.0)

View File

@ -24,6 +24,6 @@
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -23,6 +23,6 @@
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -21,6 +21,6 @@
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -24,6 +24,6 @@
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -28,6 +28,6 @@
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"browserslist": "^4.19.3", "browserslist": "^4.19.3",
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -24,6 +24,6 @@
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -26,6 +26,6 @@
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -19,6 +19,6 @@
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"webpack": "^5.73.0" "webpack": "^5.84.1"
} }
} }

View File

@ -19,6 +19,6 @@
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -19,6 +19,6 @@
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.2", "@types/react-dom": "^18.0.2",
"webpack": "^5.80.0" "webpack": "^5.84.1"
} }
} }

View File

@ -65,9 +65,9 @@
"terser-webpack-plugin": "5.3.5", "terser-webpack-plugin": "5.3.5",
"typescript": "^4.6.4", "typescript": "^4.6.4",
"trusted-cert": "1.1.3", "trusted-cert": "1.1.3",
"webpack": "5.80.0", "webpack": "5.84.1",
"webpack-bundle-analyzer": "4.5.0", "webpack-bundle-analyzer": "4.5.0",
"webpack-dev-server": "4.11.1", "webpack-dev-server": "4.15.0",
"unplugin": "0.9.5", "unplugin": "0.9.5",
"bonjour-service": "^1.0.13", "bonjour-service": "^1.0.13",
"colorette": "^2.0.10", "colorette": "^2.0.10",

View File

@ -82,7 +82,7 @@
"react-router": "6.11.2", "react-router": "6.11.2",
"sass": "^1.50.0", "sass": "^1.50.0",
"unplugin": "^0.9.0", "unplugin": "^0.9.0",
"webpack": "^5.80.0", "webpack": "^5.84.1",
"webpack-dev-server": "^4.7.4" "webpack-dev-server": "^4.7.4"
}, },
"peerDependencies": { "peerDependencies": {

View File

@ -145,9 +145,9 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt
delete require.cache[serverEntry]; delete require.cache[serverEntry];
return await dynamicImport(serverEntry, true); return await dynamicImport(serverEntry, true);
} }
} catch (err) { } catch (error) {
// make error clearly, notice typeof err === 'string' // make error clearly, notice typeof err === 'string'
logger.error('Excute server entry error:', err); logger.error('Execute server entry error:', error);
return; return;
} }
} }
@ -397,9 +397,9 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt
spinner: buildSpinner, spinner: buildSpinner,
}); });
} }
} catch (err) { } catch (error) {
buildSpinner.stop(); buildSpinner.stop();
throw err; throw error;
} }
}, },
}; };

View File

@ -64,7 +64,9 @@ const scanPlugin = (options: Options): Plugin => {
pkgNameCache.set(resolved, result); pkgNameCache.set(resolved, result);
return result; return result;
} catch (err) { } catch (err) {
logger.error(`cant resolve package of path: ${resolved}`, err); logger.error(`Can't resolve package of path: ${resolved}`);
// Scan error doesn't affect the build process.
logger.error(err);
} }
}; };
@ -162,4 +164,4 @@ const scanPlugin = (options: Options): Plugin => {
}; };
}; };
export default scanPlugin; export default scanPlugin;

View File

@ -1,6 +1,4 @@
import path from 'path'; import path from 'path';
import type { TransformOptions } from 'esbuild';
import { esbuild } from '@ice/bundles';
import MagicString from '@ice/bundles/compiled/magic-string/index.js'; import MagicString from '@ice/bundles/compiled/magic-string/index.js';
import esModuleLexer from '@ice/bundles/compiled/es-module-lexer/index.js'; import esModuleLexer from '@ice/bundles/compiled/es-module-lexer/index.js';
import type { ImportSpecifier } from '@ice/bundles/compiled/es-module-lexer/index.js'; import type { ImportSpecifier } from '@ice/bundles/compiled/es-module-lexer/index.js';
@ -29,17 +27,10 @@ const transformImportPlugin = (preBundleDepsMetadata: PreBundleDepsMetaData, ser
transformInclude(id: string) { transformInclude(id: string) {
return /\.(js|jsx|ts|tsx)$/.test(id); return /\.(js|jsx|ts|tsx)$/.test(id);
}, },
async transform(source: string, id: string) { async transform(source: string) {
await init; await init;
let imports: readonly ImportSpecifier[] = []; let imports: readonly ImportSpecifier[] = [];
// es-module-lexer do not support parse jsx syntax, so we first transform the source by esbuild. imports = parse(source)[0];
const transformed = await transformWithESBuild(
source,
id,
);
source = transformed.code;
imports = parse(transformed.code)[0];
const str = new MagicString(source); const str = new MagicString(source);
for (let index = 0; index < imports.length; index++) { for (let index = 0; index < imports.length; index++) {
const { const {
@ -61,30 +52,4 @@ const transformImportPlugin = (preBundleDepsMetadata: PreBundleDepsMetaData, ser
}; };
}; };
// Fork from https://github.com/vitejs/vite/blob/d98c8a710b8f0804120c05e5bd3eb403f17e7b30/packages/vite/src/node/plugins/esbuild.ts#L60
async function transformWithESBuild(
input: string,
filePath: string,
options: TransformOptions = {},
) {
let loader = options?.loader as TransformOptions['loader'];
if (!loader) {
const extname = path.extname(filePath).slice(1);
if (extname === 'mjs' || extname === 'cjs' || extname === 'js') {
loader = 'jsx';
} else {
loader = extname as TransformOptions['loader'];
}
}
const transformOptions = {
sourcemap: true,
sourcefile: filePath,
...options,
loader,
} as TransformOptions;
return await esbuild.transform(input, transformOptions);
}
export default transformImportPlugin; export default transformImportPlugin;

View File

@ -36,19 +36,17 @@ function guessLoader(id: string): Loader {
* but esbuild needs them, we fix the two methods. * but esbuild needs them, we fix the two methods.
*/ */
export function fixSourceMap(map: any) { export function fixSourceMap(map: any) {
if (!('toString' in map)) { Object.defineProperty(map, 'toMapString', {
Object.defineProperty(map, 'toString', { enumerable: false,
enumerable: false, value: function toString() {
value: function toString() { return JSON.stringify(this);
return JSON.stringify(this); },
}, });
});
}
if (!('toUrl' in map)) { if (!('toUrl' in map)) {
Object.defineProperty(map, 'toUrl', { Object.defineProperty(map, 'toUrl', {
enumerable: false, enumerable: false,
value: function toUrl() { value: function toUrl() {
return `data:application/json;charset=utf-8;base64,${Buffer.from(this.toString()).toString('base64')}`; return `data:application/json;charset=utf-8;base64,${Buffer.from(this.toMapString()).toString('base64')}`;
}, },
}); });
} }
@ -135,13 +133,15 @@ const transformPipe = (options: PluginOptions = {}): Plugin => {
sourceCode = result; sourceCode = result;
} else if (typeof result === 'object' && result !== null) { } else if (typeof result === 'object' && result !== null) {
sourceCode = result.code; sourceCode = result.code;
sourceMap = result.map; sourceMap = typeof result.map === 'string' ? JSON.parse(result.map) : result.map;
} }
} }
if (sourceMap && typeof sourceMap !== 'string') { if (sourceMap && typeof sourceMap !== 'string') {
if (!sourceMap.sourcesContent || sourceMap.sourcesContent.length === 0) { if (!sourceMap.sourcesContent || sourceMap.sourcesContent.length === 0) {
sourceMap.sourcesContent = [sourceCode]; sourceMap.sourcesContent = [sourceCode];
} }
// Use relative path to make sure the source map is correct.
sourceMap.sources = [path.relative(resolveDir, id)];
sourceMap = fixSourceMap(sourceMap); sourceMap = fixSourceMap(sourceMap);
sourceCode += `\n//# sourceMappingURL=${sourceMap.toUrl()}`; sourceCode += `\n//# sourceMappingURL=${sourceMap.toUrl()}`;
} }
@ -158,4 +158,4 @@ const transformPipe = (options: PluginOptions = {}): Plugin => {
}; };
}; };
export default transformPipe; export default transformPipe;

View File

@ -83,12 +83,12 @@ function decodeParam(val: any) {
} }
try { try {
return decodeURIComponent(val); return decodeURIComponent(val);
} catch (err) { } catch (error) {
if (err instanceof URIError) { if (error instanceof URIError) {
err.message = `Failed to decode param ' ${val} '`; error.message = `Failed to decode param ' ${val} '`;
(err as any).status = 400; (error as any).status = 400;
(err as any).statusCode = 400; (error as any).statusCode = 400;
} }
throw err; throw error;
} }
} }

View File

@ -47,7 +47,8 @@ export default function getConfigs(rootDir: string, exclude: string[] = []): Moc
try { try {
mockModule = require(mockFile); mockModule = require(mockFile);
} catch (error) { } catch (error) {
logger.error(`Failed to parse mock file ${mockFile}.\n${error.message}`); logger.error(`Failed to parse mock file ${mockFile}`);
logger.error(error);
return; return;
} }
const config = mockModule.default || mockModule || {}; const config = mockModule.default || mockModule || {};

View File

@ -135,7 +135,7 @@ export async function analyzeImports(files: string[], options: Options) {
})(); })();
})); }));
} catch (err) { } catch (err) {
logger.error('[ERROR]', `optimize runtime failed when analyze ${filePath}`); logger.briefError(`Optimize runtime failed when analyze ${filePath}`);
logger.debug(err); logger.debug(err);
throw err; throw err;
} }
@ -151,8 +151,7 @@ export async function analyzeImports(files: string[], options: Options) {
})); }));
} }
return importSet; return importSet;
} catch (err) { } catch (_) {
logger.debug(err);
return false; return false;
} }
} }
@ -199,8 +198,8 @@ export async function scanImports(entries: string[], options?: ScanOptions) {
); );
logger.debug(`Scan completed in ${(performance.now() - start).toFixed(2)}ms:`, deps); logger.debug(`Scan completed in ${(performance.now() - start).toFixed(2)}ms:`, deps);
} catch (error) { } catch (error) {
logger.error('Failed to scan module imports.', `\n${error.message}`); logger.briefError('Failed to scan module imports.');
logger.debug(error.stack); logger.debug(error);
} }
return orderedDependencies(deps); return orderedDependencies(deps);
} }
@ -256,8 +255,8 @@ export async function getFileExports(options: FileOptions): Promise<CachedRouteE
} }
} }
} catch (error) { } catch (error) {
logger.error(`Failed to get route ${filePath} exports.`, `\n${error.message}`); logger.briefError(`Failed to get route ${filePath} exports.`);
logger.debug(error.stack); logger.debug(error);
cached = { cached = {
exports: [], exports: [],
hash: fileHash, hash: fileHash,

View File

@ -135,11 +135,8 @@ export const getAppExportConfig = (rootDir: string) => {
transformInclude: (id) => id.includes('src/app') || id.includes('.ice'), transformInclude: (id) => id.includes('src/app') || id.includes('.ice'),
getOutfile, getOutfile,
needRecompile: async (entry, keepExports) => { needRecompile: async (entry, keepExports) => {
let cached = null;
const cachedKey = `app_${keepExports.join('_')}_${process.env.__ICE_VERSION__}`; const cachedKey = `app_${keepExports.join('_')}_${process.env.__ICE_VERSION__}`;
try { const cached = await getCache(rootDir, cachedKey);
cached = await getCache(rootDir, cachedKey);
} catch (err) { }
const fileHash = await getFileHash(appEntry); const fileHash = await getFileHash(appEntry);
if (!cached || fileHash !== cached) { if (!cached || fileHash !== cached) {
await setCache(rootDir, cachedKey, fileHash); await setCache(rootDir, cachedKey, fileHash);
@ -153,8 +150,8 @@ export const getAppExportConfig = (rootDir: string) => {
try { try {
return (await config.getConfig(exportNames || ['default', 'defineAppConfig'])) || {}; return (await config.getConfig(exportNames || ['default', 'defineAppConfig'])) || {};
} catch (error) { } catch (error) {
logger.warn('Failed to get app config.', `\n${error.message}`); logger.briefError('Failed to get app config.');
logger.debug(error.stack); logger.debug(error);
} }
}; };
@ -163,8 +160,8 @@ export const getAppExportConfig = (rootDir: string) => {
try { try {
config.setCompiler(serverCompiler); config.setCompiler(serverCompiler);
} catch (error) { } catch (error) {
logger.error('Failed to compile app config.', `\n${error.message}`); logger.briefError('Failed to compile app config.');
logger.debug(error.stack); logger.debug(error);
} }
}, },
getAppConfig, getAppConfig,
@ -203,15 +200,12 @@ export const getRouteExportConfig = (rootDir: string) => {
rootDir, rootDir,
getOutfile: getRouteConfigOutfile, getOutfile: getRouteConfigOutfile,
needRecompile: async (entry) => { needRecompile: async (entry) => {
let cached = false; const cached = await getCache(rootDir, cachedKey);
try {
cached = await getCache(rootDir, cachedKey);
} catch (err) { }
if (cached) { if (cached) {
// Always use cached file path while `routes-config` trigger re-compile by webpack plugin. // Always use cached file path while `routes-config` trigger re-compile by webpack plugin.
return entry; return entry;
} else { } else {
setCache(rootDir, cachedKey, 'true'); await setCache(rootDir, cachedKey, 'true');
return false; return false;
} }
}, },
@ -222,16 +216,13 @@ export const getRouteExportConfig = (rootDir: string) => {
rootDir, rootDir,
getOutfile: getdataLoadersConfigOutfile, getOutfile: getdataLoadersConfigOutfile,
needRecompile: async (entry) => { needRecompile: async (entry) => {
let cached = false;
const cachedKey = `loader_config_file_${process.env.__ICE_VERSION__}`; const cachedKey = `loader_config_file_${process.env.__ICE_VERSION__}`;
try { const cached = await getCache(rootDir, cachedKey);
cached = await getCache(rootDir, cachedKey);
} catch (err) { }
if (cached) { if (cached) {
// Always use cached file path while `routes-config` trigger re-compile by webpack plugin. // Always use cached file path while `routes-config` trigger re-compile by webpack plugin.
return entry; return entry;
} else { } else {
setCache(rootDir, cachedKey, 'true'); await setCache(rootDir, cachedKey, 'true');
return false; return false;
} }
}, },
@ -259,7 +250,7 @@ export const getRouteExportConfig = (rootDir: string) => {
const ensureRoutesConfig = async () => { const ensureRoutesConfig = async () => {
const configFile = await routeConfig.getConfigFile(['pageConfig']); const configFile = await routeConfig.getConfigFile(['pageConfig']);
if (!configFile) { if (!configFile) {
setCache(rootDir, cachedKey, ''); await setCache(rootDir, cachedKey, '');
} }
}; };
@ -269,14 +260,14 @@ export const getRouteExportConfig = (rootDir: string) => {
try { try {
routeConfig.setCompiler(serverCompiler); routeConfig.setCompiler(serverCompiler);
} catch (error) { } catch (error) {
routeConfigLogger.error('Failed to get route config.', `\n${error.message}`); routeConfigLogger.briefError('Failed to get route config.');
routeConfigLogger.debug(error.stack); routeConfigLogger.debug(error);
} }
try { try {
dataloaderConfig.setCompiler(serverCompiler); dataloaderConfig.setCompiler(serverCompiler);
} catch (error) { } catch (error) {
dataLoaderConfigLogger.error('Failed to get dataLoader config.', `\n${error.message}`); dataLoaderConfigLogger.briefError('Failed to get dataLoader config.');
dataLoaderConfigLogger.debug(error.stack); dataLoaderConfigLogger.debug(error);
} }
}, },
getRoutesConfig, getRoutesConfig,

View File

@ -111,7 +111,7 @@ export default async function preBundleDeps(
metadata, metadata,
}; };
} catch (error) { } catch (error) {
logger.error('Failed to bundle dependencies.'); logger.briefError('Failed to bundle dependencies.');
logger.debug(error); logger.debug(error);
return {}; return {};
} }

View File

@ -128,8 +128,7 @@ export function createServerCompiler(options: Options) {
return (source: string, id: string) => { return (source: string, id: string) => {
return { return {
...getConfig(source, id), ...getConfig(source, id),
// Force inline when use swc as a transformer. sourceMaps: !!sourceMap,
sourceMaps: sourceMap && 'inline',
}; };
}; };
} }
@ -254,13 +253,11 @@ export function createServerCompiler(options: Options) {
serverEntry, serverEntry,
}; };
} catch (error) { } catch (error) {
logger.error( logger.briefError(
'Server compiled with errors.', 'Server compiled with errors.',
`\nEntryPoints: ${JSON.stringify(buildOptions.entryPoints)}`, `\nEntryPoints: ${JSON.stringify(buildOptions.entryPoints)}`,
`\n${error.message}`, `\n${error.message}`,
); );
// TODO: Log esbuild options with namespace.
// logger.debug('esbuild options: ', buildOptions);
logger.debug(error.stack); logger.debug(error.stack);
return { return {
error: error as Error, error: error as Error,

View File

@ -136,7 +136,7 @@ async function webpackCompiler(options: {
const firstWebpackConfig = webpackConfigs[0]; const firstWebpackConfig = webpackConfigs[0];
firstWebpackConfig.plugins.push((compiler: webpack.Compiler) => { firstWebpackConfig.plugins.push((compiler: webpack.Compiler) => {
compiler.hooks.beforeCompile.tap('spinner', () => { compiler.hooks.beforeCompile.tap('spinner', () => {
spinner.text = 'compiling...\n'; spinner.text = 'Compiling...\n';
}); });
compiler.hooks.afterEmit.tap('spinner', () => { compiler.hooks.afterEmit.tap('spinner', () => {
spinner.stop(); spinner.stop();
@ -146,9 +146,9 @@ async function webpackCompiler(options: {
try { try {
// @ts-ignore // @ts-ignore
compiler = webpackBundler(webpackConfigs); compiler = webpackBundler(webpackConfigs);
} catch (err) { } catch (error) {
logger.error('Webpack compile error.'); logger.error('Webpack compile error.');
logger.error(err.message || err); logger.error(error);
} }
let isFirstCompile = true; let isFirstCompile = true;

View File

@ -39,9 +39,9 @@ export default async function generateEntry(options: Options): Promise<EntryResu
let serverEntry; let serverEntry;
try { try {
serverEntry = await dynamicImport(entry); serverEntry = await dynamicImport(entry);
} catch (err) { } catch (error) {
// make error clearly, notice typeof err === 'string' logger.error(`Error occurred while importing ${entry}`);
throw new Error(`import ${entry} error: ${err}`); throw error;
} }
// When enable hash-router, only generate one html(index.html). // When enable hash-router, only generate one html(index.html).

View File

@ -1,8 +1,9 @@
import type { Consola } from 'consola'; import type { Consola, ConsolaLogObject } from 'consola';
import consola from 'consola'; import consola from 'consola';
// In ice.js, we use DEBUG_TAG instead of DEBUG to avoid other libs which use `DEBUG` as their flag log debug info. // In ice.js, we use DEBUG_TAG instead of DEBUG to avoid other libs which use `DEBUG` as their flag log debug info.
const { DEBUG_TAG } = process.env; // eslint-disable-next-line camelcase
const { DEBUG_TAG, npm_lifecycle_event } = process.env;
function getEnableAndDisabledNamespaces(namespaces?: string) { function getEnableAndDisabledNamespaces(namespaces?: string) {
const enabledNamespaces: RegExp[] = []; const enabledNamespaces: RegExp[] = [];
@ -52,22 +53,37 @@ export type CreateLoggerReturnType = Pick<Consola, |
'ready' | 'ready' |
'debug' | 'debug' |
'trace' 'trace'
>; > & { briefError?: (message: ConsolaLogObject | any, ...args: any[]) => void };
export type CreateLogger = (namespace?: ICELogNamespace) => CreateLoggerReturnType; export type CreateLogger = (namespace?: ICELogNamespace) => CreateLoggerReturnType;
export const createLogger: CreateLogger = (namespace) => { export const createLogger: CreateLogger = (namespace) => {
function briefError(message: ConsolaLogObject | any, ...args: any[]) {
consola.error(message, ...args);
if (!DEBUG_TAG) {
// eslint-disable-next-line camelcase
consola.log(`run \`DEBUG_TAG=${namespace || '*'} npm run ${npm_lifecycle_event || 'start'}\` to view error details`);
}
}
function extendLoggerInstance(instance: Consola): CreateLoggerReturnType {
const logger = {} as CreateLoggerReturnType;
['fatal', 'error', 'warn', 'log', 'info', 'start', 'success', 'ready', 'debug', 'trace'].forEach((method) => {
logger[method] = instance[method];
});
logger.briefError = briefError;
return logger;
}
if (DEBUG_TAG) { if (DEBUG_TAG) {
consola.level = 4; consola.level = 4;
} }
if (!namespace) { if (!namespace) {
return consola; return extendLoggerInstance(consola);
} }
if (DEBUG_TAG) { if (DEBUG_TAG) {
if (enabled(namespace)) { if (enabled(namespace)) {
return consola.withTag(namespace); return extendLoggerInstance(consola.withTag(namespace));
} else { } else {
return { return {
fatal() { }, fatal() { },
@ -80,10 +96,11 @@ export const createLogger: CreateLogger = (namespace) => {
ready() { }, ready() { },
debug() { }, debug() { },
trace() { }, trace() { },
briefError() {},
}; };
} }
} else { } else {
return consola.withTag(namespace); return extendLoggerInstance(consola.withTag(namespace));
} }
}; };

View File

@ -154,4 +154,4 @@ function openBrowser(url) {
} }
} }
export default openBrowser; export default openBrowser;

View File

@ -3,12 +3,18 @@ import cacache from '@ice/bundles/compiled/cacache/index.js';
const CACHE_PATH = 'node_modules/.cache/route'; const CACHE_PATH = 'node_modules/.cache/route';
export function getCache(rootDir: string, id: string) { export async function getCache(rootDir: string, id: string) {
const cachePath = path.join(rootDir, CACHE_PATH); const cachePath = path.join(rootDir, CACHE_PATH);
return cacache.get(cachePath, id).then((cache) => JSON.parse(cache.data.toString('utf-8'))); try {
return await cacache.get(cachePath, id)
.then((cache) => JSON.parse(cache.data.toString('utf-8')));
} catch (_) {
// Ignore get cache error.
return null;
}
} }
export function setCache(rootDir: string, id: string, data: any) { export async function setCache(rootDir: string, id: string, data: any) {
const cachePath = path.join(rootDir, CACHE_PATH); const cachePath = path.join(rootDir, CACHE_PATH);
return cacache.put(cachePath, id, JSON.stringify(data)); return await cacache.put(cachePath, id, JSON.stringify(data));
} }

View File

@ -0,0 +1,5 @@
import { defineAppConfig } from '@ice/runtime';
import { getAppConfig } from '@ice/runtime/client';
console.log(getAppConfig);
export default defineAppConfig({});

View File

@ -13,7 +13,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
const alias = { '@': path.join(__dirname, './fixtures/scan') }; const alias = { '@': path.join(__dirname, './fixtures/scan') };
const rootDir = path.join(__dirname, './fixtures/scan'); const rootDir = path.join(__dirname, './fixtures/scan');
const cacheDir = path.join(rootDir, '.cache'); const cacheDir = path.join(rootDir, '.cache');
const appEntry = path.join(__dirname, './fixtures/scan/app.ts'); const appEntry = path.join(__dirname, './fixtures/scan/import.js');
const outdir = path.join(rootDir, 'build'); const outdir = path.join(rootDir, 'build');
it('transform module import', async () => { it('transform module import', async () => {
@ -35,7 +35,7 @@ it('transform module import', async () => {
transformImportPlugin(), transformImportPlugin(),
], ],
}); });
const buildContent = await fse.readFile(path.join(outdir, 'app.js')); const buildContent = await fse.readFile(path.join(outdir, 'import.js'), 'utf-8');
expect(buildContent.includes('../../.cache/deps/@ice_runtime_client.mjs')).toBeTruthy(); expect(buildContent.includes('../../.cache/deps/@ice_runtime_client.mjs')).toBeTruthy();
expect(buildContent.includes('../../.cache/deps/@ice_runtime.mjs')).toBeTruthy(); expect(buildContent.includes('../../.cache/deps/@ice_runtime.mjs')).toBeTruthy();
}); });

View File

@ -21,7 +21,7 @@
"@ice/bundles": "^0.1.10" "@ice/bundles": "^0.1.10"
}, },
"devDependencies": { "devDependencies": {
"webpack": "^5.80.0" "webpack": "^5.84.1"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

@ -49,7 +49,7 @@
"devDependencies": { "devDependencies": {
"@ice/app": "^3.2.0", "@ice/app": "^3.2.0",
"@ice/runtime": "^1.2.0", "@ice/runtime": "^1.2.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
}, },
"repository": { "repository": {
"type": "http", "type": "http",

View File

@ -28,7 +28,7 @@
"@ice/app": "^3.2.0", "@ice/app": "^3.2.0",
"build-scripts": "^2.1.1-0", "build-scripts": "^2.1.1-0",
"esbuild": "^0.17.16", "esbuild": "^0.17.16",
"webpack": "^5.80.0", "webpack": "^5.84.1",
"webpack-dev-server": "^4.9.2" "webpack-dev-server": "^4.9.2"
}, },
"repository": { "repository": {

View File

@ -62,7 +62,7 @@ export default async function generateManifest({
// dataLoader may have side effect code. // dataLoader may have side effect code.
dataloaderConfig = await getDataloaderConfig(); dataloaderConfig = await getDataloaderConfig();
} catch (err) { } catch (err) {
logger.debug('GetDataloaderConfig failed.'); logger.briefError('GetDataloaderConfig failed.');
logger.debug(err); logger.debug(err);
} }

View File

@ -38,7 +38,7 @@ const createPHAMiddleware = ({
// dataLoader may have side effect code. // dataLoader may have side effect code.
dataloaderConfig = await getDataloaderConfig(); dataloaderConfig = await getDataloaderConfig();
} catch (err) { } catch (err) {
logger.debug('GetDataloaderConfig failed.'); logger.briefError('GetDataloaderConfig failed.');
logger.debug(err); logger.debug(err);
} }

View File

@ -31,7 +31,7 @@
}, },
"devDependencies": { "devDependencies": {
"@ice/app": "^3.2.1", "@ice/app": "^3.2.1",
"webpack": "^5.80.0" "webpack": "^5.84.1"
}, },
"repository": { "repository": {
"type": "http", "type": "http",

View File

@ -26,7 +26,7 @@
"devDependencies": { "devDependencies": {
"esbuild": "^0.17.16", "esbuild": "^0.17.16",
"postcss": "^8.4.18", "postcss": "^8.4.18",
"webpack": "^5.80.0", "webpack": "^5.84.1",
"webpack-dev-server": "^4.7.4" "webpack-dev-server": "^4.7.4"
}, },
"scripts": { "scripts": {

View File

@ -94,8 +94,9 @@ export async function redirectImport(code: string, options: Options): Promise<st
let imports: readonly ImportSpecifier[] = []; let imports: readonly ImportSpecifier[] = [];
try { try {
imports = parse(code)[0]; imports = parse(code)[0];
} catch (e) { } catch (error) {
consola.debug('[parse error]', e); consola.error('Parse error when redirect import.');
consola.error(error);
} }
if (!imports.length) { if (!imports.length) {
return code; return code;

View File

@ -16,7 +16,7 @@
}, },
"devDependencies": { "devDependencies": {
"@ice/webpack-config": "^1.0.0", "@ice/webpack-config": "^1.0.0",
"webpack": "^5.80.0" "webpack": "^5.84.1"
}, },
"scripts": { "scripts": {
"watch": "tsc -w", "watch": "tsc -w",

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@
"glob": "^7.2.3", "glob": "^7.2.3",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"typescript": "^4.9.5", "typescript": "^4.9.5",
"webpack": "^5.80.0" "webpack": "^5.84.1"
}, },
"browserslist": { "browserslist": {
"production": [ "production": [