Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions examples/basic-project/compatHtml.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from '@ice/app';
import defaultConfig from './ice.config.mjs';

export default defineConfig(() => ({
...defaultConfig,
htmlGenerating: {
mode: 'compat'
}
}));
7 changes: 6 additions & 1 deletion examples/with-suspense-ssr/src/document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ function Document() {
</head>
<body>
<Main />
<script dangerouslySetInnerHTML={{ __html: 'window.addEventListener(\'suspense\', (d) => console.log(\'suspence event=\', d))' }} />
<script
defer
dangerouslySetInnerHTML={{
__html: "window.addEventListener('ice-suspense', (e) => console.log('ice-suspense', e));",
}}
/>
<Scripts async />
</body>
</html>
Expand Down
2 changes: 1 addition & 1 deletion examples/with-suspense-ssr/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function Home() {
<h2>Home Page</h2>
<Counter />
<Comments id="comments" fallback={<div>loading...</div>} />
<Footer id="comments" fallback={<div>loading...</div>} />
<Footer id="comments-2" fallback={<div>loading...</div>} />
</div>
);
}
Expand Down
10 changes: 10 additions & 0 deletions packages/bundles/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 0.2.8

### Patch Changes

- 97cb2046: @ice/app: align the output result with the former esbuild
@ice/bundles: export more webpack internal modules
- 97cb2046: @ice/app: remove unused deps and import them from @ice/bundles
@ice/bundles: compile tsconfig-paths-webpack-plugin
- a0099df5: fix: update es-module-lexer

## 0.2.7

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/bundles/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ice/bundles",
"version": "0.2.7",
"version": "0.2.8",
"license": "MIT",
"author": "ICE",
"description": "Basic dependencies for ice.",
Expand Down Expand Up @@ -63,7 +63,7 @@
"css-loader": "6.7.1",
"css-minimizer-webpack-plugin": "3.4.1",
"cssnano": "^5.1.7",
"es-module-lexer": "0.10.5",
"es-module-lexer": "1.6.0",
"esbuild-register": "3.4.1",
"eslint": "^8.14.0",
"eslint-webpack-plugin": "3.1.1",
Expand Down
5 changes: 5 additions & 0 deletions packages/bundles/webpack/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ module.exports = {
SingleEntryPlugin: require('webpack/lib/SingleEntryPlugin'),
FetchCompileAsyncWasmPlugin: require('webpack/lib/web/FetchCompileAsyncWasmPlugin'),
FetchCompileWasmPlugin: require('webpack/lib/web/FetchCompileWasmPlugin'),
JavascriptModulesPlugin: require('webpack/lib/javascript/JavascriptModulesPlugin'),
StartupChunkDependenciesPlugin: require('webpack/lib/runtime/StartupChunkDependenciesPlugin'),
StartupHelpers: require('webpack/lib/javascript/StartupHelpers'),
compileBooleanMatcher: require('webpack/lib/util/compileBooleanMatcher'),
identifier: require('webpack/lib/util/identifier'),
StringXor: require('webpack/lib/util/StringXor'),
NormalModule: require('webpack/lib/NormalModule'),
EntryDependency: require('webpack/lib/dependencies/EntryDependency'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').JavascriptModulesPlugin;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').StartupChunkDependenciesPlugin;
1 change: 1 addition & 0 deletions packages/bundles/webpack/packages/StartupHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').StartupHelpers;
1 change: 1 addition & 0 deletions packages/bundles/webpack/packages/compileBooleanMatcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').compileBooleanMatcher;
1 change: 1 addition & 0 deletions packages/bundles/webpack/packages/identifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./bundle').identifier;
36 changes: 36 additions & 0 deletions packages/ice/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
# Changelog

## 3.6.0

### Minor Changes

- 97cb2046: support split server bundle

### Patch Changes

- f0c6380b: feat: add htmlGenerating `mode` option
- 97cb2046: @ice/app: align the output result with the former esbuild
@ice/bundles: export more webpack internal modules
- 97cb2046: @ice/app: remove unused deps and import them from @ice/bundles
@ice/bundles: compile tsconfig-paths-webpack-plugin
- 97cb2046: rebase releast/next
- 15cd5f7f: fix: glob pattern for document
- 97cb2046: feat: minify css file;
feat: change minifier from terser to esbuildMinifier.
feat: support config minify option
- 97cb2046: - feat: change transformInclude to array
- fix: only treat .js as jsx
- feat: support customize webpack.module.rule
- feat: support handle assets
- 97cb2046: refactro: reuse webpackConfig
- 97cb2046: fix: use @ice/bundles instead of import webpack directly.
feat: support pass definitions for provide plugin.
- Updated dependencies [97cb2046]
- Updated dependencies [97cb2046]
- Updated dependencies [a0099df5]
- Updated dependencies [a0099df5]
- Updated dependencies [97cb2046]
- @ice/[email protected]
- @ice/[email protected]
- @ice/[email protected]
- @ice/[email protected]
- @ice/[email protected]

## 3.5.1

### Patch Changes
Expand Down
8 changes: 4 additions & 4 deletions packages/ice/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ice/app",
"version": "3.5.1",
"version": "3.6.0",
"description": "provide scripts and configuration used by web framework ice",
"type": "module",
"main": "./esm/index.js",
Expand Down Expand Up @@ -62,15 +62,15 @@
"chokidar": "^3.5.3",
"commander": "^9.0.0",
"consola": "^2.15.3",
"cross-spawn": "^7.0.3",
"cross-spawn": "^7.0.5",
"detect-port": "^1.3.0",
"dotenv": "^16.0.0",
"dotenv-expand": "^8.0.3",
"ejs": "^3.1.10",
"fast-glob": "^3.2.11",
"find-up": "^5.0.0",
"fs-extra": "^10.0.0",
"micromatch": "^4.0.5",
"micromatch": "^4.0.8",
"mlly": "^1.1.0",
"mrmime": "^1.0.0",
"open": "^8.4.0",
Expand Down Expand Up @@ -109,4 +109,4 @@
"publishConfig": {
"access": "public"
}
}
}
6 changes: 5 additions & 1 deletion packages/ice/src/bundler/config/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import injectInitialEntry from '../../utils/injectInitialEntry.js';
import { SERVER_OUTPUT_DIR } from '../../constant.js';
import { logger } from '../../utils/logger.js';
import type { BundlerOptions } from '../types.js';
import type { HtmlGeneratingMode } from '../../types/index.js';

export async function getOutputPaths(options: {
rootDir: string;
Expand All @@ -21,7 +22,8 @@ export async function getOutputPaths(options: {
}
}
if (serverEntry && userConfig.htmlGenerating) {
outputPaths = await buildCustomOutputs(rootDir, outputDir, serverEntry, bundleOptions);
const htmlGeneratingMode = typeof userConfig.htmlGenerating === 'boolean' ? undefined : userConfig.htmlGenerating?.mode;
outputPaths = await buildCustomOutputs(rootDir, outputDir, serverEntry, bundleOptions, htmlGeneratingMode);
}
return outputPaths;
}
Expand All @@ -37,6 +39,7 @@ async function buildCustomOutputs(
outputDir: string,
serverEntry: string,
bundleOptions: Pick<BundlerOptions, 'userConfig' | 'appConfig' | 'routeManifest'>,
generatingMode?: HtmlGeneratingMode,
) {
const { userConfig, appConfig, routeManifest } = bundleOptions;
const { ssg } = userConfig;
Expand All @@ -52,6 +55,7 @@ async function buildCustomOutputs(
renderMode: ssg ? 'SSG' : undefined,
routeType: appConfig?.router?.type,
routeManifest,
generatingMode,
});
if (routeType === 'memory' && userConfig?.routes?.injectInitialEntry) {
injectInitialEntry(routeManifest, outputDir);
Expand Down
2 changes: 1 addition & 1 deletion packages/ice/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ const userConfig = [
},
{
name: 'htmlGenerating',
validation: 'boolean',
validation: 'boolean|object',
defaultValue: true,
},
];
Expand Down
24 changes: 17 additions & 7 deletions packages/ice/src/requireHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,24 @@ export function getHookFiles() {
'webpack/lib/ExternalsPlugin',
'webpack/lib/web/FetchCompileAsyncWasmPlugin',
'webpack/lib/web/FetchCompileWasmPlugin',
'webpack/lib/runtime/StartupChunkDependenciesPlugin',
'webpack/lib/javascript/JavascriptModulesPlugin',
'webpack/lib/javascript/StartupHelpers',
'webpack/lib/util/identifier',
'webpack/lib/util/compileBooleanMatcher',
];
const webpackDir = path.join(require.resolve('@ice/bundles/compiled/webpack'), '../');
const pluginMap = webpackPlugins.map((pluginPath) => {
return [pluginPath, pluginPath.replace(/^webpack\/lib\/((web|node|optimize|webworker)\/)?/, webpackDir)];
return [
pluginPath,
pluginPath.replace(/^webpack\/lib\/((web|node|optimize|webworker|runtime|javascript|util)\/)?/, webpackDir),
];
});
const pluginMapWithJs = webpackPlugins.map((pluginPath) => {
return [
`${pluginPath}.js`,
pluginPath.replace(/^webpack\/lib\/((web|node|optimize|webworker|runtime|javascript|util)\/)?/, webpackDir),
];
});

return [
Expand All @@ -42,6 +56,7 @@ export function getHookFiles() {
['webpack/hot/only-dev-server', `${webpackDir}hot/only-dev-server`],
['webpack/hot/emitter', `${webpackDir}hot/emitter`],
...pluginMap,
...pluginMapWithJs,
];
}

Expand All @@ -52,12 +67,7 @@ function hijackWebpack() {
// eslint-disable-next-line global-require
const mod = require('module');
const resolveFilename = mod._resolveFilename;
mod._resolveFilename = function (
request: string,
parent: any,
isMain: boolean,
options: any,
) {
mod._resolveFilename = function (request: string, parent: any, isMain: boolean, options: any) {
const hookResolved = hookPropertyMap.get(request);
if (hookResolved) request = hookResolved;
return resolveFilename.call(mod, request, parent, isMain, options);
Expand Down
39 changes: 29 additions & 10 deletions packages/ice/src/service/serverCompiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import { scanImports } from './analyze.js';
import type { PreBundleDepsMetaData } from './preBundleDeps.js';
import preBundleDeps from './preBundleDeps.js';
import { WebpackServerCompiler } from './webpackServerCompiler/compiler.js';
import VirualAssetPlugin from './webpackServerCompiler/virtualAssetPlugin.js';

const logger = createLogger('server-compiler');

Expand Down Expand Up @@ -100,7 +102,6 @@
const externals = task.config?.externals || {};
const sourceMap = task.config?.sourceMap;
const dev = command === 'start';

// Filter empty alias.
const { ignores, alias } = filterAlias(task.config?.alias || {});

Expand Down Expand Up @@ -144,6 +145,7 @@
redirectImports,
getRoutesFile,
}, 'esbuild', { isServer });

const define = getRuntimeDefination(task.config?.define || {}, runtimeDefineVars, transformEnv);
if (preBundle) {
const plugins = [
Expand All @@ -169,7 +171,7 @@
plugins,
});
}

server.bundler = server.bundler ?? 'esbuild';
const format = customBuildOptions?.format || 'esm';

let buildOptions: esbuild.BuildOptions = {
Expand Down Expand Up @@ -236,35 +238,52 @@
}

const startTime = new Date().getTime();
logger.debug('[esbuild]', `start compile for: ${JSON.stringify(buildOptions.entryPoints)}`);
logger.debug(`[${server.bundler}]`, `start compile for: ${JSON.stringify(buildOptions.entryPoints)}`);

try {
let esbuildResult: esbuild.BuildResult;
let bundleResult: any;
let context: esbuild.BuildContext;
if (dev) {
context = await esbuild.context(buildOptions);
esbuildResult = await context.rebuild();
bundleResult = await context.rebuild();
} else {
esbuildResult = await esbuild.build(buildOptions);
switch (server.bundler) {
case 'webpack':
const webpackServerCompiler = new WebpackServerCompiler({

Check warning on line 252 in packages/ice/src/service/serverCompiler.ts

View workflow job for this annotation

GitHub Actions / build (18.x, ubuntu-latest)

Unexpected lexical declaration in case block

Check warning on line 252 in packages/ice/src/service/serverCompiler.ts

View workflow job for this annotation

GitHub Actions / build (16.x, windows-latest)

Unexpected lexical declaration in case block

Check warning on line 252 in packages/ice/src/service/serverCompiler.ts

View workflow job for this annotation

GitHub Actions / build (16.x, ubuntu-latest)

Unexpected lexical declaration in case block

Check warning on line 252 in packages/ice/src/service/serverCompiler.ts

View workflow job for this annotation

GitHub Actions / build (18.x, windows-latest)

Unexpected lexical declaration in case block
...buildOptions,
externals,
compileIncludes: task.config.compileIncludes,
plugins: [compilationInfo && new VirualAssetPlugin({ compilationInfo, rootDir })],
rootDir,
userServerConfig: server,
runtimeDefineVars,
});
bundleResult = (await webpackServerCompiler.build())?.compilation;
break;
case 'esbuild':
default:
bundleResult = await esbuild.build(buildOptions);
break;
}
}

logger.debug('[esbuild]', `time cost: ${new Date().getTime() - startTime}ms`);
logger.debug(`[${server.bundler}]`, `time cost: ${new Date().getTime() - startTime}ms`);

const esm = server?.format === 'esm';
const outJSExtension = esm ? '.mjs' : '.cjs';
const serverEntry = path.join(rootDir, task.config.outputDir, SERVER_OUTPUT_DIR, `index${outJSExtension}`);

if (removeOutputs && esbuildResult.metafile) {
if (removeOutputs && bundleResult.metafile) {
// build/server/a.mjs -> a.mjs
const currentOutputFiles = Object.keys(esbuildResult.metafile.outputs)
const currentOutputFiles = Object.keys(bundleResult.metafile.outputs)
.map(output => output.replace(formatPath(`${path.relative(rootDir, buildOptions.outdir)}${path.sep}`), ''));
const allOutputFiles = fg.sync('**', { cwd: buildOptions.outdir });
const outdatedFiles = difference(allOutputFiles, currentOutputFiles);
outdatedFiles.forEach(outdatedFile => fse.removeSync(path.join(buildOptions.outdir, outdatedFile)));
}

return {
...esbuildResult,
...bundleResult,
context,
serverEntry,
};
Expand Down
Loading
Loading