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: basic support of asset bundleless #221

Merged
merged 3 commits into from
Sep 23, 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
5 changes: 5 additions & 0 deletions .changeset/good-fishes-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rslib/core': patch
---

realease
Binary file added e2e/assets/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions e2e/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion e2e/cases/banner-footer/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import './index.css';
// import './index.css';
import { foo } from './foo';

export const text = foo;
102 changes: 102 additions & 0 deletions e2e/cases/bundle-false/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`svgr in bundleless 1`] = `
"import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__ from \\"react/jsx-runtime\\";
import \\"react\\";
const SvgLogo = (props)=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)(\\"svg\\", {
xmlns: \\"http://www.w3.org/2000/svg\\",
viewBox: \\"0 0 841.9 595.3\\",
...props,
children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)(\\"g\\", {
fill: \\"#61DAFB\\",
children: [
/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)(\\"path\\", {
d: \\"M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3m-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9m-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9m32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1M421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32m-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24q7.05 12 14.4 23.4M420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32m-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9m-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6s22.9-35.6 58.3-50.6c8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2M310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7m237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1m38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6M320.8 78.4\\"
}),
/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)(\\"circle\\", {
cx: 420.9,
cy: 296.5,
r: 45.7
}),
/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)(\\"path\\", {
d: \\"M520.5 78.1\\"
})
]
})
});
/* harmony default export */ const logoreact = SvgLogo;
/* harmony default export */ const src = logoreact;
export { src as default };
"
`;

exports[`svgr in bundleless 2`] = `
"\\"use strict\\";
// The require scope
var __webpack_require__ = {};
/************************************************************************/ // webpack/runtime/define_property_getters
(()=>{
__webpack_require__.d = function(exports1, definition) {
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
enumerable: true,
get: definition[key]
});
};
})();
// webpack/runtime/has_own_property
(()=>{
__webpack_require__.o = function(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
};
})();
// webpack/runtime/make_namespace_object
(()=>{
// define __esModule on exports
__webpack_require__.r = function(exports1) {
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
value: 'Module'
});
Object.defineProperty(exports1, '__esModule', {
value: true
});
};
})();
/************************************************************************/ var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
default: ()=>/* binding */ src
});
const jsx_runtime_namespaceObject = require(\\"react/jsx-runtime\\");
require(\\"react\\");
const SvgLogo = (props)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(\\"svg\\", {
xmlns: \\"http://www.w3.org/2000/svg\\",
viewBox: \\"0 0 841.9 595.3\\",
...props,
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(\\"g\\", {
fill: \\"#61DAFB\\",
children: [
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(\\"path\\", {
d: \\"M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3m-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9m-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9m32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1M421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32m-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24q7.05 12 14.4 23.4M420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32m-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9m-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6s22.9-35.6 58.3-50.6c8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2M310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7m237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1m38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6M320.8 78.4\\"
}),
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(\\"circle\\", {
cx: 420.9,
cy: 296.5,
r: 45.7
}),
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(\\"path\\", {
d: \\"M520.5 78.1\\"
})
]
})
});
/* harmony default export */ const logoreact = SvgLogo;
/* harmony default export */ const src = logoreact;
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
});
"
`;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "bundle-false-relative-import-test",
"name": "bundle-false-asset-test",
"version": "1.0.0",
"private": true,
"type": "module"
Expand Down
24 changes: 24 additions & 0 deletions e2e/cases/bundle-false/asset/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper';
import { defineConfig } from '@rslib/core';

export default defineConfig({
lib: [
generateBundleEsmConfig({
bundle: false,
}),
generateBundleCjsConfig({
bundle: false,
}),
],
// do not inline svg
output: {
dataUriLimit: {
svg: 0,
},
},
source: {
entry: {
index: ['./src/**'],
},
},
});
5 changes: 5 additions & 0 deletions e2e/cases/bundle-false/asset/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import image from '../../../../assets/image.png';
import logoURL from '../../../../assets/logo.svg';

console.log(logoURL);
console.log(image);
28 changes: 26 additions & 2 deletions e2e/cases/bundle-false/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ test('single file', async () => {
`);
});

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

for (const importer of [
Expand All @@ -62,3 +62,27 @@ test('auto add extension for relative import', async () => {
expect(Object.values(contents.cjs)[3]).toContain(requirer);
}
});

test('asset in bundleless', async () => {
const fixturePath = join(__dirname, 'asset');
const { contents } = await buildAndGetResults(fixturePath);

const assets = [
'const image_namespaceObject = __webpack_require__.p + "static/image/image.png";',
'const logo_namespaceObject = __webpack_require__.p + "static/svg/logo.svg";',
];

for (const asset of assets) {
expect(Object.values(contents.esm)[0]).toContain(asset);
expect(Object.values(contents.cjs)[0]).toContain(asset);
}
});

test('svgr in bundleless', async () => {
const fixturePath = join(__dirname, 'svgr');
const { contents } = await buildAndGetResults(fixturePath);

// TODO: import "react"; in output now, we should shake this
expect(Object.values(contents.esm)[0]).toMatchSnapshot();
expect(Object.values(contents.cjs)[0]).toMatchSnapshot();
});
6 changes: 6 additions & 0 deletions e2e/cases/bundle-false/js-extension/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "bundle-false-js-extension-test",
"version": "1.0.0",
"private": true,
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { bar } from './bar';
import { baz } from './baz.js';
// @ts-ignore
import { foo } from './foo.js';
// @ts-ignore
import { qux } from './qux.cjs';

export const text = foo + bar + baz + qux;
13 changes: 13 additions & 0 deletions e2e/cases/bundle-false/svgr/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "bundle-false-svgr-test",
"version": "1.0.0",
"private": true,
"type": "module",
"dependencies": {
"react": "^18.3.1"
},
"devDependencies": {
"@rsbuild/plugin-react": "1.0.2",
"@rsbuild/plugin-svgr": "1.0.2"
}
}
21 changes: 21 additions & 0 deletions e2e/cases/bundle-false/svgr/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginSvgr } from '@rsbuild/plugin-svgr';
import { defineConfig } from '@rslib/core';

export default defineConfig({
lib: [
generateBundleEsmConfig({
bundle: false,
}),
generateBundleCjsConfig({
bundle: false,
}),
],
source: {
entry: {
index: ['./src/**'],
},
},
plugins: [pluginReact(), pluginSvgr()],
});
3 changes: 3 additions & 0 deletions e2e/cases/bundle-false/svgr/src/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Logo from '../../../../assets/logo.svg?react';

export default Logo;
28 changes: 22 additions & 6 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import {
} from '@rsbuild/core';
import glob from 'fast-glob';
import {
DEFAULT_CONFIG_EXTENSIONS,
DEFAULT_CONFIG_NAME,
DEFAULT_EXTENSIONS,
ENTRY_EXTENSIONS_PATTERN,
JS_EXTENSIONS_PATTERN,
SWC_HELPERS,
} from './constant';
import { pluginCjsShim } from './plugins/cjsShim';
Expand Down Expand Up @@ -60,7 +62,9 @@ export function defineConfig(config: RslibConfigExport) {
}

const findConfig = (basePath: string): string | undefined => {
return DEFAULT_EXTENSIONS.map((ext) => basePath + ext).find(fs.existsSync);
return DEFAULT_CONFIG_EXTENSIONS.map((ext) => basePath + ext).find(
fs.existsSync,
);
};

const resolveConfigPath = (root: string, customConfig?: string): string => {
Expand Down Expand Up @@ -644,10 +648,15 @@ const composeEntryConfig = async (
}

// Turn entries in array into each separate entry.
const resolvedEntryFiles = await glob(entryFiles, {
const globEntryFiles = await glob(entryFiles, {
cwd: root,
});

// Filter the glob resolved entry files based on the allowed extensions
const resolvedEntryFiles = globEntryFiles.filter((file) =>
ENTRY_EXTENSIONS_PATTERN.test(file),
);

if (resolvedEntryFiles.length === 0) {
throw new Error(`Cannot find ${resolvedEntryFiles}`);
}
Expand Down Expand Up @@ -693,9 +702,16 @@ const composeBundleConfig = (
// user should use copy to keep origin file or use another separate entry to deal this
let request = data.request;
if (request[0] === '.') {
request = extname(request)
? request.replace(/\.[^.]+$/, jsExtension)
: `${request}${jsExtension}`;
if (extname(request)) {
if (JS_EXTENSIONS_PATTERN.test(request)) {
request = request.replace(/\.[^.]+$/, jsExtension);
} else {
// If it does not match jsExtensionsPattern, we should do nothing, eg: ./foo.png
fi3ework marked this conversation as resolved.
Show resolved Hide resolved
return callback();
}
} else {
request = `${request}${jsExtension}`;
}
}

return callback(null, request);
Expand Down
37 changes: 36 additions & 1 deletion packages/core/src/constant.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const DEFAULT_CONFIG_NAME = 'rslib.config';

export const DEFAULT_EXTENSIONS = [
export const DEFAULT_CONFIG_EXTENSIONS = [
'.js',
'.ts',
'.mjs',
Expand All @@ -10,3 +10,38 @@ export const DEFAULT_EXTENSIONS = [
] as const;

export const SWC_HELPERS = '@swc/helpers';

export const JS_EXTENSIONS: string[] = [
'js',
'mjs',
'jsx',
'ts',
'mts',
'tsx',
'cjs',
'cjsx',
'mjsx',
'mtsx',
'cts',
'ctsx',
] as const;

export const CSS_EXTENSIONS: string[] = [
'css',
'sass',
fi3ework marked this conversation as resolved.
Show resolved Hide resolved
'scss',
'less',
] as const;

export const ENTRY_EXTENSIONS: string[] = [
...JS_EXTENSIONS,
...CSS_EXTENSIONS,
] as const;

export const JS_EXTENSIONS_PATTERN: RegExp = new RegExp(
`\\.(${JS_EXTENSIONS.join('|')})$`,
);

export const ENTRY_EXTENSIONS_PATTERN: RegExp = new RegExp(
`\\.(${ENTRY_EXTENSIONS.join('|')})$`,
);
Loading
Loading