Skip to content

Commit

Permalink
feat: implement basic bundleless support (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework authored Jul 22, 2024
1 parent 77d73df commit e7bcaf1
Show file tree
Hide file tree
Showing 28 changed files with 360 additions and 111 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
},
"typescript.tsdk": "node_modules/typescript/lib"
}
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ The project is still under development, so it possible dependents on unstable Rs

Current unstable versions are:

<!-- | Package | Version | Link |
| ------------ | ------------------------------------------------------- | --------------------------------------------------------- |
| @rspack/core | @rspack/[email protected] | [PR](https://github.com/webpack/webpack/pull/11751/files) | -->
| Package | Link |
| ------------ | ------------------------------------------------------- |
| @rspack/core | [PR](https://github.com/web-infra-dev/rspack/pull/7210) |
6 changes: 2 additions & 4 deletions e2e/cases/alias/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export { a };
`;

exports[`source.alias 2`] = `
"(() => { // webpackBootstrap
"use strict";
""use strict";
var __webpack_exports__ = {};
;// CONCATENATED MODULE: ./src/a.ts
Expand All @@ -28,6 +27,5 @@ console.info(a);
var __webpack_export_target__ = exports;
for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', { value: true });
})()
;"
"
`;
12 changes: 6 additions & 6 deletions e2e/cases/alias/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { expect, test } from 'vitest';
import { buildAndGetEntryJsResults } from '#shared';
import { buildAndGetJsResults } from '#shared';

test('source.alias', async () => {
const fixturePath = __dirname;
const { contents } = await buildAndGetEntryJsResults(fixturePath);
const { entries } = await buildAndGetJsResults(fixturePath);

expect(contents.esm).toContain('hello world');
expect(contents.cjs).toContain('hello world');
expect(entries.esm).toContain('hello world');
expect(entries.cjs).toContain('hello world');

// simple artifacts check
expect(contents.esm).toMatchSnapshot();
expect(contents.cjs).toMatchSnapshot();
expect(entries.esm).toMatchSnapshot();
expect(entries.cjs).toMatchSnapshot();
});
14 changes: 7 additions & 7 deletions e2e/cases/autoExtension/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { extname, join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetEntryJsResults } from '#shared';
import { buildAndGetJsResults } from '#shared';

test('autoExtension generate .mjs in build artifacts with esm format when type is commonjs', async () => {
const fixturePath = join(__dirname, 'type-commonjs');
const { files } = await buildAndGetEntryJsResults(fixturePath);
expect(extname(files.esm!)).toEqual('.mjs');
expect(extname(files.cjs!)).toEqual('.js');
const { entryFiles } = await buildAndGetJsResults(fixturePath);
expect(extname(entryFiles.esm!)).toEqual('.mjs');
expect(extname(entryFiles.cjs!)).toEqual('.js');
});

test('autoExtension generate .cjs in build artifacts with cjs format when type is module', async () => {
const fixturePath = join(__dirname, 'type-module');
const { files } = await buildAndGetEntryJsResults(fixturePath);
expect(extname(files.esm!)).toEqual('.js');
expect(extname(files.cjs!)).toEqual('.cjs');
const { entryFiles } = await buildAndGetJsResults(fixturePath);
expect(extname(entryFiles.esm!)).toEqual('.js');
expect(extname(entryFiles.cjs!)).toEqual('.cjs');
});
18 changes: 18 additions & 0 deletions e2e/cases/bundle-false/basic/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineConfig } from '@rslib/core';
import { generateBundleCjsConfig, generateBundleEsmConfig } from '#shared';

export default defineConfig({
lib: [
generateBundleEsmConfig(__dirname, {
bundle: false,
}),
generateBundleCjsConfig(__dirname, {
bundle: false,
}),
],
source: {
entry: {
main: ['./src/**'],
},
},
});
3 changes: 3 additions & 0 deletions e2e/cases/bundle-false/basic/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './utils/numbers';
export * from './utils/strings';
export * from './sum';
5 changes: 5 additions & 0 deletions e2e/cases/bundle-false/basic/src/sum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { num1, num2, num3 } from './utils/numbers';
import { str1, str2, str3 } from './utils/strings';

export const numSum = num1 + num2 + num3;
export const strSum = str1 + str2 + str3;
3 changes: 3 additions & 0 deletions e2e/cases/bundle-false/basic/src/utils/numbers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const num1 = 1;
export const num2 = 2;
export const num3 = 3;
3 changes: 3 additions & 0 deletions e2e/cases/bundle-false/basic/src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const str1 = 'str1';
export const str2 = 'str2';
export const str3 = 'str3';
7 changes: 7 additions & 0 deletions e2e/cases/bundle-false/basic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@rslib/tsconfig/base",
"compilerOptions": {
"baseUrl": "./"
},
"include": ["src"]
}
13 changes: 13 additions & 0 deletions e2e/cases/bundle-false/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetJsResults } from '#shared';

test('bundle: false', async () => {
const fixturePath = join(__dirname, 'basic');
const { files } = await buildAndGetJsResults(fixturePath);

// TODO: record file paths with inline snapshot
// need to add path serialization
expect(files.esm?.length).toBe(4);
expect(files.cjs?.length).toBe(4);
});
12 changes: 6 additions & 6 deletions e2e/cases/define/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { expect, test } from 'vitest';
import { buildAndGetEntryJsResults } from '#shared';
import { buildAndGetJsResults } from '#shared';

test('source.define', async () => {
const fixturePath = __dirname;
const { contents } = await buildAndGetEntryJsResults(fixturePath);
const { entries } = await buildAndGetJsResults(fixturePath);

expect(contents.esm).not.toContain('console.info(VERSION)');
expect(contents.esm).toContain('1.0.0');
expect(entries.esm).not.toContain('console.info(VERSION)');
expect(entries.esm).toContain('1.0.0');

expect(contents.cjs).not.toContain('console.info(VERSION)');
expect(contents.cjs).toContain('1.0.0');
expect(entries.cjs).not.toContain('console.info(VERSION)');
expect(entries.cjs).toContain('1.0.0');
});
4 changes: 2 additions & 2 deletions e2e/cases/externals/browser/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetEntryJsResults } from '#shared';
import { buildAndGetJsResults } from '#shared';

test('should fail to build when `output.target` is not "node"', async () => {
const fixturePath = join(__dirname);
const build = buildAndGetEntryJsResults(fixturePath);
const build = buildAndGetJsResults(fixturePath);
await expect(build).rejects.toThrowError('Rspack build failed!');
});
8 changes: 4 additions & 4 deletions e2e/cases/externals/node/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { join } from 'node:path';
import { expect, test } from 'vitest';
import { buildAndGetEntryJsResults } from '#shared';
import { buildAndGetJsResults } from '#shared';

test('auto externalize Node.js built-in modules when `output.target` is "node"', async () => {
const fixturePath = join(__dirname);
const { contents } = await buildAndGetEntryJsResults(fixturePath);
const { entries } = await buildAndGetJsResults(fixturePath);

for (const external of [
'import * as __WEBPACK_EXTERNAL_MODULE_fs__ from "fs"',
'import * as __WEBPACK_EXTERNAL_MODULE_node_assert__ from "node:assert"',
'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"',
]) {
expect(contents.esm).toContain(external);
expect(entries.esm).toContain(external);
}

for (const external of [
'var external_fs_namespaceObject = require("fs");',
'var external_node_assert_namespaceObject = require("node:assert");',
'var external_react_namespaceObject = require("react");',
]) {
expect(contents.cjs).toContain(external);
expect(entries.cjs).toContain(external);
}
});
10 changes: 5 additions & 5 deletions e2e/cases/syntax/config/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { expect, test } from 'vitest';
import { buildAndGetEntryJsResults } from '#shared';
import { buildAndGetJsResults } from '#shared';

test('should downgrade class private method by default', async () => {
const fixturePath = __dirname;
const { contents } = await buildAndGetEntryJsResults(fixturePath);
const { entries } = await buildAndGetJsResults(fixturePath);

expect(contents.esm).toMatchSnapshot();
expect(contents.esm).not.toContain('#bar');
expect(entries.esm).toMatchSnapshot();
expect(entries.esm).not.toContain('#bar');

expect(contents.cjs).toContain('#bar');
expect(entries.cjs).toContain('#bar');
});
10 changes: 5 additions & 5 deletions e2e/cases/syntax/default/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { expect, test } from 'vitest';
import { buildAndGetEntryJsResults } from '#shared';
import { buildAndGetJsResults } from '#shared';

test('should downgrade class private method by default', async () => {
const fixturePath = __dirname;
const { contents } = await buildAndGetEntryJsResults(fixturePath);
const { entries } = await buildAndGetJsResults(fixturePath);

expect(contents.esm).toMatchSnapshot();
expect(contents.esm).toContain('#bar');
expect(entries.esm).toMatchSnapshot();
expect(entries.esm).toContain('#bar');

expect(contents.cjs).toContain('#bar');
expect(entries.cjs).toContain('#bar');
});
32 changes: 22 additions & 10 deletions e2e/scripts/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,51 @@ export function generateBundleCjsConfig(
return mergeConfig(cjsBasicConfig, config)!;
}

export async function getEntryJsResults(rslibConfig: RslibConfig) {
const files: Record<string, string> = {};
const contents: Record<string, string> = {};
export async function getJsResults(rslibConfig: RslibConfig) {
const files: Record<string, string[]> = {};
const contents: Record<string, Record<string, string>> = {};
const entries: Record<string, string> = {};
const entryFiles: Record<string, string> = {};

for (const libConfig of rslibConfig.lib) {
const result = await globContentJSON(libConfig?.output?.distPath?.root!, {
const content = await globContentJSON(libConfig?.output?.distPath?.root!, {
absolute: true,
ignore: ['/**/*.map'],
});

const entryJs = Object.keys(result).find((file) =>
const jsFiles = Object.keys(content).filter((file) =>
/\.(js|cjs|mjs)$/.test(file),
);

if (entryJs) {
files[libConfig.format!] = entryJs;
contents[libConfig.format!] = result[entryJs]!;
if (jsFiles.length) {
files[libConfig.format!] = jsFiles;
contents[libConfig.format!] = content;
}

// Only applied in bundle mode, a shortcut to get single entry result
if (libConfig.bundle !== false && jsFiles.length === 1) {
entries[libConfig.format!] = Object.values(content)[0]!;
entryFiles[libConfig.format!] = jsFiles[0]!;
}
}

return {
files,
contents,
entries,
entryFiles,
};
}

export const buildAndGetEntryJsResults = async (fixturePath: string) => {
export const buildAndGetJsResults = async (fixturePath: string) => {
const rslibConfig = await loadConfig(join(fixturePath, 'rslib.config.ts'));
process.chdir(fixturePath);
await build(rslibConfig);
const results = await getEntryJsResults(rslibConfig);
const results = await getJsResults(rslibConfig);
return {
contents: results.contents,
files: results.files,
entries: results.entries,
entryFiles: results.entryFiles,
};
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@biomejs/biome": "^1.8.3",
"@modern-js/module-tools": "^2.55.0",
"@types/fs-extra": "^11.0.4",
"@types/node": "~18.19.39",
"check-dependency-version-consistency": "^4.1.0",
"cross-env": "^7.0.3",
"cspell-ban-words": "^0.0.3",
Expand All @@ -47,7 +48,7 @@
},
"pnpm": {
"overrides": {
"@rspack/core": "1.0.0-alpha.3"
"@rspack/core": "npm:@rspack/core-canary@1.0.0-canary-d77b591-20240718094414"
}
}
}
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"devDependencies": {
"@rslib/tsconfig": "workspace:*",
"@types/fs-extra": "^11.0.4",
"fast-glob": "^3.3.2",
"commander": "^12.1.0",
"fs-extra": "^11.2.0",
"picocolors": "1.0.1",
Expand Down
1 change: 1 addition & 0 deletions packages/core/prebundle.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default {
},
dependencies: [
'commander',
'fast-glob',
{
name: 'picocolors',
beforeBundle({ depPath }) {
Expand Down
Loading

0 comments on commit e7bcaf1

Please sign in to comment.