Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add js extension for relative import in bundleless mode #90

Merged
merged 4 commits into from
Aug 15, 2024
Merged
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
12 changes: 12 additions & 0 deletions e2e/cases/bundle-false/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,15 @@ test('single file', async () => {
]
`);
});

test('auto add extension for relative import', async () => {
const fixturePath = join(__dirname, 'relative-import');
const { contents } = await buildAndGetResults(fixturePath);

expect(Object.values(contents.esm)[1]).toContain(
'import * as __WEBPACK_EXTERNAL_MODULE__bar_js__ from "./bar.js";',
);
expect(Object.values(contents.cjs)[1]).toContain(
'var external_bar_cjs_namespaceObject = require("./bar.cjs");',
);
});
6 changes: 6 additions & 0 deletions e2e/cases/bundle-false/relative-import/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "bundle-false-relative-import-test",
"version": "1.0.0",
"private": true,
"type": "module"
}
18 changes: 18 additions & 0 deletions e2e/cases/bundle-false/relative-import/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper';
import { defineConfig } from '@rslib/core';

export default defineConfig({
lib: [
generateBundleEsmConfig(__dirname, {
bundle: false,
}),
generateBundleCjsConfig(__dirname, {
bundle: false,
}),
],
source: {
entry: {
main: ['./src/**'],
},
},
});
1 change: 1 addition & 0 deletions e2e/cases/bundle-false/relative-import/src/bar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const bar = 'bar';
3 changes: 3 additions & 0 deletions e2e/cases/bundle-false/relative-import/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { bar } from './bar';

export const foo = 'foo' + bar;
7 changes: 7 additions & 0 deletions e2e/cases/bundle-false/relative-import/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: 7 additions & 6 deletions e2e/scripts/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ type BuildResult = {

export async function getResults(
rslibConfig: RslibConfig,
fixturePath: string,
type: 'js' | 'dts',
): Promise<Omit<BuildResult, 'rspackConfig' | 'rsbuildConfig' | 'isSuccess'>> {
const files: Record<string, string[]> = {};
Expand All @@ -81,7 +80,9 @@ export async function getResults(
ignore: ['**/*.map'],
});

const fileSet = Object.keys(content).filter((file) => regex.test(file));
const fileSet = Object.keys(content)
.filter((file) => regex.test(file))
.sort();
const filterContent: Record<string, string> = {};
for (const key of fileSet) {
if (content[key]) {
Expand All @@ -90,7 +91,7 @@ export async function getResults(
}

if (fileSet.length) {
files[libConfig.format!] = fileSet.sort();
files[libConfig.format!] = fileSet;
contents[libConfig.format!] = filterContent;
}

Expand Down Expand Up @@ -131,8 +132,8 @@ export async function buildAndGetResults(
origin: { bundlerConfigs, rsbuildConfig },
} = await rsbuildInstance.inspectConfig({ verbose: true });
if (type === 'all') {
const jsResults = await getResults(rslibConfig, fixturePath, 'js');
const dtsResults = await getResults(rslibConfig, fixturePath, 'dts');
const jsResults = await getResults(rslibConfig, 'js');
const dtsResults = await getResults(rslibConfig, 'dts');
return {
js: {
contents: jsResults.contents,
Expand All @@ -155,7 +156,7 @@ export async function buildAndGetResults(
};
}

const results = await getResults(rslibConfig, fixturePath, type);
const results = await getResults(rslibConfig, type);
return {
contents: results.contents,
files: results.files,
Expand Down
25 changes: 20 additions & 5 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ const composeAutoExtensionConfig = (
pkgJson?: PkgJson,
): {
config: RsbuildConfig;
jsExtension: string;
dtsExtension: string;
} => {
const { jsExtension, dtsExtension } = getDefaultExtension({
Expand All @@ -257,6 +258,7 @@ const composeAutoExtensionConfig = (
},
},
},
jsExtension,
dtsExtension,
};
};
Expand Down Expand Up @@ -381,7 +383,10 @@ const composeEntryConfig = async (
};
};

const composeBundleConfig = (bundle = true): RsbuildConfig => {
const composeBundleConfig = (
jsExtension: string,
bundle = true,
): RsbuildConfig => {
if (bundle) return {};

return {
Expand All @@ -391,7 +396,14 @@ const composeBundleConfig = (bundle = true): RsbuildConfig => {
// Issuer is not empty string when the module is imported by another module.
// Prevent from externalizing entry modules here.
if (data.contextInfo.issuer) {
return callback(null, data.request);
// Node.js ECMAScript module loader does no extension searching.
// So we add a file extension here when data.request is a relative path
return callback(
null,
data.request[0] === '.'
? `${data.request}${jsExtension}`
: data.request,
);
}
callback();
},
Expand Down Expand Up @@ -474,9 +486,12 @@ async function composeLibRsbuildConfig(

const { format, autoExtension = true, autoExternal = true } = config;
const formatConfig = composeFormatConfig(format!);
const { config: autoExtensionConfig, dtsExtension } =
composeAutoExtensionConfig(format!, autoExtension, pkgJson);
const bundleConfig = composeBundleConfig(config.bundle);
const {
config: autoExtensionConfig,
jsExtension,
dtsExtension,
} = composeAutoExtensionConfig(format!, autoExtension, pkgJson);
const bundleConfig = composeBundleConfig(jsExtension, config.bundle);
const targetConfig = composeTargetConfig(config.output?.target);
const syntaxConfig = composeSyntaxConfig(
config.output?.syntax,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const nodeBuiltInModules: Array<string | RegExp> = [
'pnpapi',
];

async function calcLongestCommonPath(
export async function calcLongestCommonPath(
absPaths: string[],
): Promise<string | null> {
if (absPaths.length === 0) {
Expand Down Expand Up @@ -126,4 +126,4 @@ export const readPackageJson = (rootPath: string): undefined | PkgJson => {
export const isObject = (obj: unknown): obj is Record<string, any> =>
Object.prototype.toString.call(obj) === '[object Object]';

export { color, calcLongestCommonPath };
export { color };
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading