Merge pull request #6369 from alibaba/release/next

Release 3.2.7
This commit is contained in:
ClarkXia 2023-07-06 17:26:40 +08:00 committed by GitHub
commit ae705c03e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 441 additions and 56 deletions

View File

@ -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

View File

@ -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",

View File

@ -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 {

View File

@ -389,6 +389,11 @@ const userConfig = [
validation: 'object',
defaultValue: {},
},
{
name: 'htmlGenerating',
validation: 'boolean',
defaultValue: true,
},
];
const cliOption = [

View File

@ -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;
}

View File

@ -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}`);

View File

@ -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'];
}

View File

@ -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(' & ') %><% } %>;

View File

@ -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,');
});
});

View File

@ -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"

View File

@ -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

View File

@ -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",

View File

@ -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) {

View File

@ -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

View File

@ -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"
}
}
}

View File

@ -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');

View File

@ -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;

View File

@ -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

View File

@ -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",

View File

@ -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;
}

View File

@ -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;

View File

@ -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');
});
});

View File

@ -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==}

View File

@ -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');

View File

@ -642,6 +642,13 @@ export default defineConfig(() => ({
}));
```
### htmlGenerating
- 类型:`boolean`
- 默认值:`true`
如果产物不想生成 html可以设置为 `false`,在 SSG 开启的情况下,强制关闭 html 生成,将导致 SSG 失效。
### plugins
- 类型:`PluginList<Config, OverwritePluginAPI>`