mirror of https://github.com/alibaba/ice.git
commit
ae705c03e8
|
|
@ -1,5 +1,16 @@
|
|||
# Changelog
|
||||
|
||||
## 3.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 429a2a83: fix: relative id in pipe transform
|
||||
- c7aad4eb: chore: add user config comments
|
||||
- d8f4520f: fix: alias for type declaration
|
||||
- 110b282b: feat: support user config htmlGenerating to control the generation of html
|
||||
- Updated dependencies [29ad1b52]
|
||||
- @ice/runtime@1.2.5
|
||||
|
||||
## 3.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@ice/app",
|
||||
"version": "3.2.6",
|
||||
"version": "3.2.7",
|
||||
"description": "provide scripts and configuration used by web framework ice",
|
||||
"type": "module",
|
||||
"main": "./esm/index.js",
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
"dependencies": {
|
||||
"@ice/bundles": "0.1.12",
|
||||
"@ice/route-manifest": "1.2.0",
|
||||
"@ice/runtime": "^1.2.4",
|
||||
"@ice/runtime": "^1.2.5",
|
||||
"@ice/webpack-config": "1.0.18",
|
||||
"@swc/helpers": "0.5.1",
|
||||
"@types/express": "^4.17.14",
|
||||
|
|
|
|||
|
|
@ -142,13 +142,17 @@ const build = async (
|
|||
distType,
|
||||
prependCode,
|
||||
},
|
||||
htmlGenerating,
|
||||
} = userConfig;
|
||||
let renderMode: RenderMode;
|
||||
if (ssg) {
|
||||
renderMode = 'SSG';
|
||||
if (!htmlGenerating) {
|
||||
logger.warn('SSG depends on htmlGenerating, SSG will not work when htmlGenerating is set to false.');
|
||||
}
|
||||
}
|
||||
const { serverEntry } = await serverCompileTask.get() || {};
|
||||
if (serverEntry) {
|
||||
if (serverEntry && htmlGenerating) {
|
||||
serverEntryRef.current = serverEntry;
|
||||
const routeType = appConfig?.router?.type;
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -389,6 +389,11 @@ const userConfig = [
|
|||
validation: 'object',
|
||||
defaultValue: {},
|
||||
},
|
||||
{
|
||||
name: 'htmlGenerating',
|
||||
validation: 'boolean',
|
||||
defaultValue: true,
|
||||
},
|
||||
];
|
||||
|
||||
const cliOption = [
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ const transformPipe = (options: PluginOptions = {}): Plugin => {
|
|||
const resolveDir = path.dirname(args.path);
|
||||
const loader = guessLoader(id);
|
||||
|
||||
// If file extension is not recognized, return it to esbuild.
|
||||
if (!loader) {
|
||||
// If file extension is not recognized and load path is relative, return it to esbuild.
|
||||
if (!loader || !path.isAbsolute(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,11 +86,11 @@ export function generateDeclaration(exportList: Array<TargetDeclarationData | De
|
|||
const symbol = type ? ';' : ',';
|
||||
|
||||
if (specifier) {
|
||||
importDeclarations.push(`import ${type ? 'type ' : ''}${isDefaultImport ? specifier : `{ ${specifiers.map(specifierStr => (specifierStr)).join(', ')} }`} from '${source}';`);
|
||||
importDeclarations.push(`import ${type ? 'type ' : ''}${isDefaultImport ? specifier : `{ ${specifiers.map(specifierStr => ((alias && alias[specifierStr]) ? `${specifierStr} as ${alias[specifierStr]}` : specifierStr)).join(', ')} }`} from '${source}';`);
|
||||
|
||||
specifiers.forEach((specifierStr) => {
|
||||
if (alias && alias[specifierStr]) {
|
||||
exportDeclarations.push(`${specifierStr} as ${alias[specifierStr]}${symbol}`);
|
||||
exportDeclarations.push(`${alias[specifierStr]}${symbol}`);
|
||||
exportNames.push(alias[specifierStr]);
|
||||
} else {
|
||||
exportDeclarations.push(`${specifierStr}${symbol}`);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ interface SyntaxFeatures {
|
|||
}
|
||||
|
||||
interface Optimization {
|
||||
/**
|
||||
* Optimize code by remove react-router dependencies when set to true.
|
||||
*/
|
||||
router?: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -33,6 +36,10 @@ interface Fetcher {
|
|||
}
|
||||
|
||||
export interface UserConfig {
|
||||
/**
|
||||
* Feature polyfill for legacy browsers, which can not polyfilled by core-js.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#featurepolyfill
|
||||
*/
|
||||
featurePolyfill?: {
|
||||
abortcontroller?: boolean | string;
|
||||
};
|
||||
|
|
@ -40,53 +47,213 @@ export interface UserConfig {
|
|||
distType: Array<DistType> | DistType;
|
||||
prependCode?: string;
|
||||
};
|
||||
/**
|
||||
* Alias for import certain modules more easily.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#alias
|
||||
*/
|
||||
alias?: Record<string, string | false>;
|
||||
/**
|
||||
* Define global constants which can be configured at compile time.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#define
|
||||
*/
|
||||
define?: Record<string, string | boolean>;
|
||||
/**
|
||||
* Configure the publicPath, it only works in dev mode.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#devpublicpath
|
||||
*/
|
||||
devPublicPath?: string;
|
||||
/**
|
||||
* Configure the publicPath, it only works in prod mode.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#publicpath
|
||||
*/
|
||||
publicPath?: string;
|
||||
/**
|
||||
* Configure hash based file name.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#hash
|
||||
*/
|
||||
hash?: boolean | string;
|
||||
/**
|
||||
* Configure externals to prevent bundling certain imported packages and
|
||||
* instead retrieve these external dependencies at runtime.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#externals
|
||||
*/
|
||||
externals?: Config['externals'];
|
||||
/**
|
||||
* The output directory for build command.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#outputdir
|
||||
*/
|
||||
outputDir?: string;
|
||||
/**
|
||||
* Proxy configuration for dev server, as same as webpack devServer.proxy.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#proxy
|
||||
*/
|
||||
proxy?: Config['proxy'];
|
||||
/**
|
||||
* Polyfill mode for legacy browsers, works with .browserslistrc, support entry and usage.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#polyfill
|
||||
*/
|
||||
polyfill?: Config['polyfill'];
|
||||
/**
|
||||
* Configure the output file name of build bundle.
|
||||
*/
|
||||
filename?: string;
|
||||
/**
|
||||
* Modify the webpack configuration, it is not recommended.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#webpack
|
||||
*/
|
||||
webpack?: ModifyWebpackConfig;
|
||||
postcss?: ProcessOptions & { plugins?: (string | [string, Record<string, any>?])[] };
|
||||
/**
|
||||
* Allows to set PostCSS options and plugins.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#postcss
|
||||
*/
|
||||
postcss?: ProcessOptions & {
|
||||
plugins?: (string | [string, Record<string, any>?])[];
|
||||
};
|
||||
/**
|
||||
* Custom file-system based route rules.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#routes
|
||||
*/
|
||||
routes?: {
|
||||
/**
|
||||
* Ignore files when generate routes when match rule.
|
||||
*/
|
||||
ignoreFiles?: string[];
|
||||
/**
|
||||
* Define route rules by API.
|
||||
*/
|
||||
defineRoutes?: (defineRoute: DefineRouteFunction) => void;
|
||||
/**
|
||||
* Define route rules by route config.
|
||||
*/
|
||||
config?: RouteItem[];
|
||||
/**
|
||||
* inject initial route path for each route html.
|
||||
*/
|
||||
injectInitialEntry?: boolean;
|
||||
};
|
||||
/**
|
||||
* Add ice.js plugin to customize framework config.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#plugins
|
||||
*/
|
||||
plugins?: PluginList<Config, OverwritePluginAPI>;
|
||||
/**
|
||||
* `console.*` will be dropped when build.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#droploglevel
|
||||
*/
|
||||
dropLogLevel?: 'trace' | 'debug' | 'log' | 'info' | 'warn' | 'error';
|
||||
/**
|
||||
* Minify build output, it only works in prod mode by default.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#minify
|
||||
*/
|
||||
minify?: boolean | 'swc' | MinifyOptions;
|
||||
/**
|
||||
* Compile dependencies, ice.js will compile all dependencies by default when build for compatibility.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#compiledependencies
|
||||
*/
|
||||
compileDependencies?: boolean | string[] | RegExp[];
|
||||
/**
|
||||
* HTML will not be generated when build, If it is false.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#htmlgenerating
|
||||
*/
|
||||
htmlGenerating?: boolean;
|
||||
/**
|
||||
* Choose a style of souce mapping to enhance the debugging process.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#sourcemap
|
||||
*/
|
||||
sourceMap?: string | boolean;
|
||||
/**
|
||||
* Check typescript when compile source code.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#tschecker
|
||||
*/
|
||||
tsChecker?: boolean;
|
||||
/**
|
||||
* Check source code by eslint if eslint options is configured.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#eslint
|
||||
*/
|
||||
eslint?: Config['eslintOptions'] | boolean;
|
||||
/**
|
||||
* A switch for SSR (Server Side Rendering)
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#ssr
|
||||
*/
|
||||
ssr?: boolean;
|
||||
/**
|
||||
* A switch for SSG (Static Site Generation), it is true by default.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#ssg
|
||||
*/
|
||||
ssg?: boolean;
|
||||
/**
|
||||
* config for server bundle
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#server
|
||||
*/
|
||||
server?: {
|
||||
/**
|
||||
* onDemand compilation for server when dev
|
||||
*/
|
||||
onDemand?: boolean;
|
||||
/**
|
||||
* bundle format for server bundle, support esm and cjs
|
||||
*/
|
||||
format?: 'esm' | 'cjs';
|
||||
/**
|
||||
* bundle server code as a single file
|
||||
*/
|
||||
bundle?: boolean;
|
||||
/**
|
||||
* ignore file when bundle server code, module return empty when match
|
||||
*/
|
||||
ignores?: IgnorePattern[];
|
||||
/**
|
||||
* externals config for server bundle
|
||||
*/
|
||||
externals?: string[];
|
||||
};
|
||||
/**
|
||||
* Optimization options for build.
|
||||
* @sse https://v3.ice.work/docs/guide/basic/config#optimization
|
||||
*/
|
||||
optimization?: Optimization;
|
||||
mock?: { exclude?: string[] };
|
||||
/**
|
||||
* Configure mock rules for development.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#mock
|
||||
*/
|
||||
mock?: {
|
||||
exclude?: string[];
|
||||
};
|
||||
/**
|
||||
* Config for experimental features.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#experimental
|
||||
*/
|
||||
experimental?: Config['experimental'];
|
||||
/**
|
||||
* Custom transform rules for source code.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#transform
|
||||
*/
|
||||
transform?: UnpluginOptions['transform'];
|
||||
/**
|
||||
* Specify the syntax features you want to use.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#syntaxfeatures
|
||||
*/
|
||||
syntaxFeatures?: SyntaxFeatures;
|
||||
/**
|
||||
* @deprecated
|
||||
* Please use `codeSplitting` instead
|
||||
*/
|
||||
splitChunks?: boolean;
|
||||
/**
|
||||
* Code splitting strategy, support page and vendors, default value is true (built-in strategy).
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#codesplitting
|
||||
*/
|
||||
codeSplitting?: 'page' | 'vendors' | boolean;
|
||||
/**
|
||||
* generate additional assets for request data, default is true
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#dataloader
|
||||
*/
|
||||
dataLoader?: {
|
||||
fetcher?: Fetcher;
|
||||
} | Boolean;
|
||||
/**
|
||||
* Enable cross-origin loading of chunks.
|
||||
* @see https://v3.ice.work/docs/guide/basic/config#crossoriginloading
|
||||
*/
|
||||
crossOriginLoading?: Config['output']['crossOriginLoading'];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<%- routeConfigTypes.imports -%>
|
||||
import type { AppConfig, RouteConfig as DefaultRouteConfig } from '@ice/runtime';
|
||||
<%- routeConfigTypes.imports -%>
|
||||
|
||||
<% if (routeConfigTypes.imports) {-%>
|
||||
type ExtendsRouteConfig = <% if (routeConfigTypes.imports) { %><%- routeConfigTypes.exportNames.join(' & ') %><% } %>;
|
||||
|
|
|
|||
|
|
@ -39,14 +39,14 @@ describe('generateDeclaration', () => {
|
|||
it('aliased exports', () => {
|
||||
const { importStr, exportStr } = generateDeclaration([{
|
||||
source: 'react-helmet',
|
||||
specifier: 'Helmet',
|
||||
specifier: ['Helmet'],
|
||||
alias: {
|
||||
Helmet: 'Head',
|
||||
},
|
||||
declarationType: DeclarationType.NORMAL,
|
||||
}]);
|
||||
expect(importStr).toBe('import Helmet from \'react-helmet\';');
|
||||
expect(exportStr).toBe('Helmet as Head,');
|
||||
expect(importStr).toBe('import { Helmet as Head } from \'react-helmet\';');
|
||||
expect(exportStr).toBe('Head,');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@
|
|||
"webpack-dev-server": "^4.13.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ice/app": "^3.2.6",
|
||||
"@ice/runtime": "^1.2.4"
|
||||
"@ice/app": "^3.2.7",
|
||||
"@ice/runtime": "^1.2.5"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
# Changelog
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 110b282b: fix: do not render document when template is set to false
|
||||
|
||||
## 3.0.0
|
||||
|
||||
### Major Changes
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@ice/plugin-pha",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"description": "ice.js plugin for PHA.",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
"htmlparser2": "^8.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ice/app": "^3.2.6",
|
||||
"@ice/app": "^3.2.7",
|
||||
"build-scripts": "^2.1.1-0",
|
||||
"esbuild": "^0.17.16",
|
||||
"webpack": "^5.86.0",
|
||||
|
|
|
|||
|
|
@ -183,9 +183,8 @@ async function getPageManifest(page: string | Page, options: ParseOptions): Prom
|
|||
key: page,
|
||||
...rest,
|
||||
};
|
||||
const html = await renderPageDocument(page, excuteServerEntry);
|
||||
if (template && !Array.isArray(pageConfig.frames)) {
|
||||
pageManifest.document = html;
|
||||
pageManifest.document = await renderPageDocument(page, excuteServerEntry);
|
||||
}
|
||||
|
||||
if (preload) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
## 0.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- dd297f96: fix: compilation config not extend
|
||||
- 7f718c5f: fix: fix Rax namespace typing compat with React v18
|
||||
- bf8af99d: remove server options setter
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@ice/plugin-rax-compat",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"description": "Provide rax compat support for ice.js",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
|
|
@ -24,13 +24,14 @@
|
|||
"babel-plugin-transform-jsx-stylesheet": "1.0.6",
|
||||
"consola": "^2.15.3",
|
||||
"css": "^2.2.1",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"rax-compat": "^0.2.1",
|
||||
"style-unit": "^3.0.5",
|
||||
"stylesheet-loader": "^0.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ice/app": "^3.2.1",
|
||||
"@ice/app": "^3.2.7",
|
||||
"@types/lodash-es": "^4.17.7",
|
||||
"webpack": "^5.86.0"
|
||||
},
|
||||
"repository": {
|
||||
|
|
@ -39,9 +40,9 @@
|
|||
},
|
||||
"scripts": {
|
||||
"watch": "tsc -w",
|
||||
"build": "tsc"
|
||||
"build": "tsc && cp src/rax-compat.d.ts esm/rax-compat.d.ts"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,18 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { createRequire } from 'module';
|
||||
import type { Plugin } from '@ice/app/types';
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
import consola from 'consola';
|
||||
import merge from 'lodash.merge';
|
||||
import { merge, cloneDeep } from 'lodash-es';
|
||||
import { transformSync } from '@babel/core';
|
||||
import styleSheetLoader from './transform-styles.js';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const jsRegex = /\.(jsx?|tsx?|mjs)$/;
|
||||
|
||||
const alias = {
|
||||
|
|
@ -62,16 +66,34 @@ export interface CompatRaxOptions {
|
|||
|
||||
const plugin: Plugin<CompatRaxOptions> = (options = {}) => ({
|
||||
name: '@ice/plugin-rax-compat',
|
||||
setup: ({ onGetConfig, context }) => {
|
||||
setup: ({ onGetConfig, context, generator }) => {
|
||||
const { userConfig } = context;
|
||||
|
||||
onGetConfig((config) => {
|
||||
// Inject rax-compat type fix in .ice/rax-compat.d.ts
|
||||
// Produce: import { type __UNUSED_TYPE_FOR_IMPORT_EFFECT_ONLY__ } from './rax-compat.d';
|
||||
generator.addRenderFile(path.join(__dirname, './rax-compat.d.ts'), 'rax-compat.d.ts', {});
|
||||
generator.addExport({
|
||||
// Avoid value import to cause Webpack compilation error:
|
||||
// 'Export assignment cannot be used when targeting ECMAScript modules.'
|
||||
specifier: ['type __UNUSED_TYPE_FOR_IMPORT_EFFECT_ONLY__'],
|
||||
source: './rax-compat.d',
|
||||
type: false,
|
||||
});
|
||||
|
||||
const compilationConfigFunc = typeof config.swcOptions?.compilationConfig === 'function'
|
||||
? config.swcOptions?.compilationConfig
|
||||
: () => config.swcOptions?.compilationConfig;
|
||||
|
||||
// Reset jsc.transform.react.runtime to classic.
|
||||
config.swcOptions = merge(config.swcOptions || {}, {
|
||||
compilationConfig: (source: string) => {
|
||||
compilationConfig: (source: string, id: string) => {
|
||||
let swcCompilationConfig = {};
|
||||
const hasJSXComment = source.indexOf('@jsx createElement') !== -1;
|
||||
const isRaxComponent = /(from|require\()\s*['"]rax['"]/.test(source);
|
||||
|
||||
if (hasJSXComment) {
|
||||
return {
|
||||
swcCompilationConfig = {
|
||||
jsc: {
|
||||
transform: {
|
||||
react: {
|
||||
|
|
@ -80,11 +102,8 @@ const plugin: Plugin<CompatRaxOptions> = (options = {}) => ({
|
|||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const isRaxComponent = /(from|require\()\s*['"]rax['"]/.test(source);
|
||||
if (isRaxComponent) {
|
||||
return {
|
||||
} else if (isRaxComponent) {
|
||||
swcCompilationConfig = {
|
||||
jsc: {
|
||||
transform: {
|
||||
react: {
|
||||
|
|
@ -94,18 +113,13 @@ const plugin: Plugin<CompatRaxOptions> = (options = {}) => ({
|
|||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!config.server) {
|
||||
config.server = {};
|
||||
}
|
||||
const originalOptions = config.server.buildOptions;
|
||||
config.server.buildOptions = (options) => ({
|
||||
...(originalOptions ? originalOptions(options) : options),
|
||||
jsx: 'transform',
|
||||
jsxFactory: 'createElement',
|
||||
jsxFragment: 'Fragment',
|
||||
return merge(
|
||||
// Clone config object to avoid Maximum call stack size exceeded error.
|
||||
cloneDeep(compilationConfigFunc(source, id)),
|
||||
swcCompilationConfig,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Object.assign(config.alias, alias);
|
||||
|
|
@ -119,6 +133,7 @@ const plugin: Plugin<CompatRaxOptions> = (options = {}) => ({
|
|||
const transformCssModule = options.cssModule == null ? true : options.cssModule;
|
||||
|
||||
if (userConfig.ssr || userConfig.ssg) {
|
||||
config.server ??= {};
|
||||
config.server.buildOptions = applyStylesheetLoaderForServer(config.server.buildOptions, transformCssModule);
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +257,7 @@ const styleSheetLoaderForClient = (config, transformCssModule) => {
|
|||
*/
|
||||
function applyStylesheetLoaderForServer(preBuildOptions, transformCssModule) {
|
||||
return (buildOptions) => {
|
||||
const currentOptions = preBuildOptions?.(buildOptions) || buildOptions;
|
||||
const currentOptions = preBuildOptions?.(buildOptions) ?? buildOptions ?? {};
|
||||
|
||||
// Remove esbuild-empty-css while use inline style.
|
||||
currentOptions.plugins = currentOptions.plugins?.filter(({ name }) => name !== 'esbuild-empty-css');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
// @ts-nocheck
|
||||
/* eslint-disable */
|
||||
import type * as React from 'react';
|
||||
|
||||
/**
|
||||
* typing overrides from commits below(@types/react since v17):
|
||||
*
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/443451ccc5db3adf1865853e152636f1a9ba5dd5
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/b57d67064938d173fa950cd519524445d20d2ef7#diff-32cfd8cb197872bcba371f5018185d2e75fa540b52cda2dd7d8ac12dcc021299
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/220087807a5746367416c2a3ef87c17d7344f22f
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/89596431d2bf885a298b369e6e53d7ede6db72fa#diff-32cfd8cb197872bcba371f5018185d2e75fa540b52cda2dd7d8ac12dcc021299
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/55dc209ceb6dbcd59c4c68cc8dfb77faadd9de12#diff-32cfd8cb197872bcba371f5018185d2e75fa540b52cda2dd7d8ac12dcc021299
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/afd309b4193c1f448386bf8fe09e512e4422e69e
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/14f568cded146f89864a06da1884364bd4e6ced0
|
||||
* https://github.com/DefinitelyTyped/DefinitelyTyped/commit/684c905d533f1a4f5a62edf9011d5eca5a9458a6
|
||||
*/
|
||||
declare namespace Rax {
|
||||
export type FC<P = {}> = React.FunctionComponent<P>;
|
||||
export type ForwardRefRenderFunction<
|
||||
T,
|
||||
P = {}
|
||||
> = React.ForwardRefRenderFunction<P>;
|
||||
export type VoidFunctionComponent<P = {}> = React.VoidFunctionComponent<P>;
|
||||
export type ForwardRefExoticComponent<P> = React.ForwardRefExoticComponent<P>
|
||||
|
||||
export type JSXElementConstructor<P> =
|
||||
| ((
|
||||
props: P,
|
||||
/**
|
||||
* @deprecated https://legacy.reactjs.org/docs/legacy-context.html#referencing-context-in-stateless-function-components
|
||||
*/
|
||||
deprecatedLegacyContext?: any
|
||||
) => React.ReactNode)
|
||||
| (new (props: P) => React.Component<any, any>);
|
||||
|
||||
export type RaxNode = React.ReactNode;
|
||||
|
||||
// Omit would not be sufficient for this. We'd like to avoid unnecessary mapping and need a distributive conditional to support unions.
|
||||
export type PropsWithoutRef<P> = React.PropsWithoutRef<P>;
|
||||
|
||||
export type PropsWithChildren<P = unknown> = React.PropsWithChildren<P>;
|
||||
|
||||
export type RaxFragment = React.ReactFragment;
|
||||
|
||||
export type ComponentPropsWithRef<T extends React.ElementType> =
|
||||
React.ComponentPropsWithRef<T>;
|
||||
|
||||
export type DependencyList = React.DependencyList;
|
||||
|
||||
export type RaxNodeArray = React.ReactNodeArray;
|
||||
|
||||
export type RaxChildren = React.ReactChildren;
|
||||
}
|
||||
export = Rax;
|
||||
export as namespace Rax;
|
||||
|
||||
export type __UNUSED_TYPE_FOR_IMPORT_EFFECT_ONLY__ = unknown;
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
# @ice/runtime
|
||||
|
||||
## 1.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 29ad1b52: fix: add warning log for mutate suspense data directly
|
||||
|
||||
## 1.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@ice/runtime",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.5",
|
||||
"description": "Runtime module for ice.js",
|
||||
"type": "module",
|
||||
"types": "./esm/index.d.ts",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import * as React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useAppContext } from './AppContext.js';
|
||||
import proxyData from './proxyData.js';
|
||||
import type { RequestContext } from './types.js';
|
||||
|
||||
const LOADER = '__ICE_SUSPENSE_LOADER__';
|
||||
|
|
@ -38,6 +39,10 @@ export function useSuspenseData(request?: Request) {
|
|||
|
||||
// 3. If request is done, return data.
|
||||
if (done) {
|
||||
if (process.env.NODE_ENV === 'development' && typeof data === 'object') {
|
||||
return proxyData(data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
function proxyData(data: any) {
|
||||
if (typeof Proxy === 'function') {
|
||||
const errorMessage = 'Do not mutate suspense data directly, it will cause unexpected behavior.';
|
||||
const handler: ProxyHandler<any> = {
|
||||
deleteProperty(target, prop) {
|
||||
console.error(errorMessage);
|
||||
delete target[prop];
|
||||
return true;
|
||||
},
|
||||
get(target, prop, receiver) {
|
||||
const value = Reflect.get(target, prop, receiver);
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return new Proxy(value, handler);
|
||||
}
|
||||
return value;
|
||||
},
|
||||
set(target, prop, value, receiver) {
|
||||
if (prop === 'length' && Array.isArray(target)) {
|
||||
if (value < target.length) {
|
||||
console.error(errorMessage, `Popping value "${target[target.length - 1]}" from array`);
|
||||
} else {
|
||||
console.error(errorMessage, `Pushing value "${value}" to array`);
|
||||
}
|
||||
} else {
|
||||
console.error(errorMessage, `Setting property "${String(prop)}" to "${value}"`);
|
||||
}
|
||||
Reflect.set(target, prop, value, receiver);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
return new Proxy(data, handler);
|
||||
} else {
|
||||
console.log('Recommend using the latest Chrome to debug suspense data.');
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
export default proxyData;
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import { expect, it, describe } from 'vitest';
|
||||
import proxyData from '../src/proxyData';
|
||||
|
||||
describe('proxyData', () => {
|
||||
it('should create a proxy for an object that intercepts property access and mutation', () => {
|
||||
const testObject = {
|
||||
name: 'John',
|
||||
age: 30,
|
||||
address: {
|
||||
street: '123 Main St',
|
||||
city: 'Anytown',
|
||||
state: 'CA',
|
||||
zip: '12345',
|
||||
},
|
||||
hobbies: ['reading', 'swimming', 'hiking'],
|
||||
};
|
||||
const proxy = proxyData(testObject);
|
||||
expect(proxy.name).toBe('John');
|
||||
expect(proxy.age).toBe(30);
|
||||
expect(proxy.address.street).toBe('123 Main St');
|
||||
expect(proxy.address.city).toBe('Anytown');
|
||||
expect(proxy.address.state).toBe('CA');
|
||||
expect(proxy.address.zip).toBe('12345');
|
||||
expect(proxy.hobbies[0]).toBe('reading');
|
||||
expect(proxy.hobbies[1]).toBe('swimming');
|
||||
expect(proxy.hobbies[2]).toBe('hiking');
|
||||
proxy.name = 'Jane';
|
||||
expect(proxy.name).toBe('Jane');
|
||||
proxy.age = 40;
|
||||
expect(proxy.age).toBe(40);
|
||||
proxy.address.street = '456 Second St';
|
||||
expect(proxy.address.street).toBe('456 Second St');
|
||||
proxy.address.city = 'Newtown';
|
||||
expect(proxy.address.city).toBe('Newtown');
|
||||
proxy.address.state = 'NY';
|
||||
expect(proxy.address.state).toBe('NY');
|
||||
proxy.address.zip = '67890';
|
||||
expect(proxy.address.zip).toBe('67890');
|
||||
proxy.hobbies.push('writing');
|
||||
expect(proxy.hobbies[3]).toBe('writing');
|
||||
});
|
||||
});
|
||||
|
|
@ -1057,7 +1057,7 @@ importers:
|
|||
specifiers:
|
||||
'@ice/bundles': 0.1.12
|
||||
'@ice/route-manifest': 1.2.0
|
||||
'@ice/runtime': ^1.2.4
|
||||
'@ice/runtime': ^1.2.5
|
||||
'@ice/webpack-config': 1.0.18
|
||||
'@swc/helpers': 0.5.1
|
||||
'@types/babel__generator': ^7.6.4
|
||||
|
|
@ -1374,7 +1374,7 @@ importers:
|
|||
|
||||
packages/plugin-pha:
|
||||
specifiers:
|
||||
'@ice/app': ^3.2.6
|
||||
'@ice/app': ^3.2.7
|
||||
'@remix-run/router': ^1.6.1
|
||||
build-scripts: ^2.1.1-0
|
||||
chalk: ^4.0.0
|
||||
|
|
@ -1403,12 +1403,13 @@ importers:
|
|||
specifiers:
|
||||
'@babel/core': ^7.0.0
|
||||
'@babel/plugin-proposal-export-default-from': ^7.18.9
|
||||
'@ice/app': ^3.2.1
|
||||
'@ice/app': ^3.2.7
|
||||
'@ice/bundles': ^0.1.10
|
||||
'@types/lodash-es': ^4.17.7
|
||||
babel-plugin-transform-jsx-stylesheet: 1.0.6
|
||||
consola: ^2.15.3
|
||||
css: ^2.2.1
|
||||
lodash.merge: ^4.6.2
|
||||
lodash-es: ^4.17.21
|
||||
rax-compat: ^0.2.1
|
||||
style-unit: ^3.0.5
|
||||
stylesheet-loader: ^0.9.1
|
||||
|
|
@ -1420,12 +1421,13 @@ importers:
|
|||
babel-plugin-transform-jsx-stylesheet: 1.0.6
|
||||
consola: 2.15.3
|
||||
css: 2.2.4
|
||||
lodash.merge: 4.6.2
|
||||
lodash-es: 4.17.21
|
||||
rax-compat: link:../rax-compat
|
||||
style-unit: 3.0.5
|
||||
stylesheet-loader: 0.9.1
|
||||
devDependencies:
|
||||
'@ice/app': link:../ice
|
||||
'@types/lodash-es': 4.17.7
|
||||
webpack: 5.86.0
|
||||
|
||||
packages/plugin-request:
|
||||
|
|
@ -7362,6 +7364,12 @@ packages:
|
|||
resolution: {integrity: sha512-1YXyYH83h6We1djyoUEqTlVyQtCfJAFXELSKW2ZRtjHD4hQ82CC4lvrv5D0l0FLcKBaiPbXyi3MpMsI9ZRgKsw==}
|
||||
dev: true
|
||||
|
||||
/@types/lodash-es/4.17.7:
|
||||
resolution: {integrity: sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==}
|
||||
dependencies:
|
||||
'@types/lodash': 4.14.191
|
||||
dev: true
|
||||
|
||||
/@types/lodash/4.14.191:
|
||||
resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==}
|
||||
dev: true
|
||||
|
|
@ -15044,6 +15052,10 @@ packages:
|
|||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
|
||||
/lodash-es/4.17.21:
|
||||
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||
dev: false
|
||||
|
||||
/lodash.camelcase/4.3.0:
|
||||
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
|
||||
dev: true
|
||||
|
|
@ -15080,6 +15092,7 @@ packages:
|
|||
|
||||
/lodash.merge/4.6.2:
|
||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||
dev: true
|
||||
|
||||
/lodash.sortby/4.7.0:
|
||||
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@ import { expect, test, describe, afterAll } from 'vitest';
|
|||
import { buildFixture, setupBrowser } from '../utils/build';
|
||||
import { startFixture, setupStartBrowser } from '../utils/start';
|
||||
import type { Page } from '../utils/browser';
|
||||
import type Browser from '../utils/browser';
|
||||
|
||||
const example = 'rax-inline-style';
|
||||
|
||||
describe(`build ${example}`, () => {
|
||||
let page: Page = null;
|
||||
let browser = null;
|
||||
let page: Page;
|
||||
let browser: Browser;
|
||||
|
||||
test('open /', async () => {
|
||||
await buildFixture(example);
|
||||
|
|
@ -31,15 +32,15 @@ describe(`build ${example}`, () => {
|
|||
});
|
||||
|
||||
describe(`start ${example}`, () => {
|
||||
let page: Page = null;
|
||||
let browser = null;
|
||||
let page: Page;
|
||||
let browser: Browser;
|
||||
|
||||
test('setup devServer', async () => {
|
||||
const { devServer, port } = await startFixture(example);
|
||||
const res = await setupStartBrowser({ server: devServer, port });
|
||||
page = res.page;
|
||||
browser = res.browser;
|
||||
await page.waitForFunction('document.getElementsByTagName(\'span\').length > 0');
|
||||
await page.waitForFunction("document.getElementsByTagName('span').length > 0");
|
||||
|
||||
// css module
|
||||
expect((await page.$$attr('img', 'class'))[0]).contain('logo');
|
||||
|
|
|
|||
|
|
@ -642,6 +642,13 @@ export default defineConfig(() => ({
|
|||
}));
|
||||
```
|
||||
|
||||
### htmlGenerating
|
||||
|
||||
- 类型:`boolean`
|
||||
- 默认值:`true`
|
||||
|
||||
如果产物不想生成 html,可以设置为 `false`,在 SSG 开启的情况下,强制关闭 html 生成,将导致 SSG 失效。
|
||||
|
||||
### plugins
|
||||
|
||||
- 类型:`PluginList<Config, OverwritePluginAPI>`
|
||||
|
|
|
|||
Loading…
Reference in New Issue