diff --git a/.changeset/perfect-chicken-travel.md b/.changeset/perfect-chicken-travel.md new file mode 100644 index 00000000..57d8d2b0 --- /dev/null +++ b/.changeset/perfect-chicken-travel.md @@ -0,0 +1,5 @@ +--- +'@ice/pkg': minor +--- + +feat: transform node_modules code when bundle mode and target is es5 diff --git a/packages/pkg/src/engine/rolldown/options.ts b/packages/pkg/src/engine/rolldown/options.ts index 89fc5ac3..b57d02c3 100644 --- a/packages/pkg/src/engine/rolldown/options.ts +++ b/packages/pkg/src/engine/rolldown/options.ts @@ -12,6 +12,8 @@ import PostcssPluginRpxToVw from 'postcss-plugin-rpx2vw'; import { visualizer } from 'rollup-plugin-visualizer'; import { JSX_RUNTIME_SOURCE } from '../../constants.js'; import { RollupOptions } from 'rollup'; +import swcPlugin from '../../rollupPlugins/swc.js'; +import { getTaskSwcOptions } from '../shared/swcConfig.js'; export function getRolldownOptions(context: Context, taskRunnerContext: TaskRunnerContext): BuildOptions[] { const { pkg, commandArgs, command, rootDir } = context; @@ -42,6 +44,8 @@ export function getRolldownOptions(context: Context, taskRunnerContext: TaskRunn } } + const isCompileToEs5 = taskConfig.formats[0].target === 'es5'; + return outputs.map((output) => { const options: BuildOptions = { // disable module type of css @@ -74,6 +78,8 @@ export function getRolldownOptions(context: Context, taskRunnerContext: TaskRunn runtime: taskConfig.jsxRuntime ?? 'automatic', importSource: JSX_RUNTIME_SOURCE, }, + // Rolldown only support ES2015 and later, So we need extra plugin to compile it + target: isCompileToEs5 ? undefined : taskConfig.formats[0].target, }; const cssMinify = taskConfig.cssMinify!(taskRunnerContext.mode, command); @@ -85,6 +91,18 @@ export function getRolldownOptions(context: Context, taskRunnerContext: TaskRunn sourceMap: taskConfig.sourcemap, }; + if (isCompileToEs5) { + const swcCompileOptions = getTaskSwcOptions(taskConfig); + plugins.push( + swcPlugin( + taskConfig.jsxRuntime, + rootDir, + swcCompileOptions, + taskConfig.type === 'bundle' && (taskConfig.compileDependencies || isCompileToEs5), + ) as any, + ); + } + plugins.push( styles( (taskConfig.modifyStylesOptions ?? [(options) => options]).reduce( diff --git a/packages/pkg/src/engine/rollup/options.ts b/packages/pkg/src/engine/rollup/options.ts index 8402140a..20ea6c0c 100644 --- a/packages/pkg/src/engine/rollup/options.ts +++ b/packages/pkg/src/engine/rollup/options.ts @@ -50,7 +50,7 @@ export function getRollupOptions(context: Context, taskRunnerContext: TaskRunner taskConfig.jsxRuntime, rootDir, swcCompileOptions, - taskConfig.type === 'bundle' && taskConfig.compileDependencies, + taskConfig.type === 'bundle' && (taskConfig.compileDependencies || taskConfig.formats[0].target === 'es5'), ), ); diff --git a/packages/pkg/src/types.ts b/packages/pkg/src/types.ts index 655e3447..8f3d41f1 100644 --- a/packages/pkg/src/types.ts +++ b/packages/pkg/src/types.ts @@ -379,6 +379,8 @@ export type EngineType = 'rollup' | 'rslib' | 'rolldown'; export interface BundleTaskConfig extends _TaskConfig, Omit { type: 'bundle'; originalFormats?: string[]; + // For normal usage(pkg mode), formats is always has one element + // For legacy usage, formats maybe has multiple elements which has same target formats: BundleFormat[]; /** * Files extensions diff --git a/tests/integration/bundle-dep/__snapshots__/index.test.ts.snap b/tests/integration/bundle-dep/__snapshots__/index.test.ts.snap index e94c0080..0758bf1d 100644 --- a/tests/integration/bundle-dep/__snapshots__/index.test.ts.snap +++ b/tests/integration/bundle-dep/__snapshots__/index.test.ts.snap @@ -1,5 +1,50 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`Run config compile-dep-when-es5 > dist structure 1`] = ` +{ + "files": [ + { + "name": "compile-dep-when-es5.esm.es2017.production.js", + }, + { + "name": "compile-dep-when-es5.esm.es5.production.js", + }, + ], + "name": "dist", +} +`; + +exports[`Run config compile-dep-when-es5 > file content dist/compile-dep-when-es5.esm.es5.production.js 1`] = ` +"function r(r,t){(null==t||t>r.length)&&(t=r.length);for(var n=0,e=Array(t);ntypeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}(a)||function(t,n){if(t){if("string"==typeof t)return r(t,void 0);var e=Object.prototype.toString.call(t).slice(8,-1);if("Object"===e&&t.constructor&&(e=t.constructor.name),"Map"===e||"Set"===e)return Array.from(e);if("Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e))return r(t,void 0)}}(a)||function(){throw TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())),n}}export{t as once}; +" +`; + +exports[`Run config compile-dep-when-es5 > file content dist/compile-dep-when-es5.esm.es2017.production.js 1`] = ` +"function n(n){let t,e=!1;return function(...r){return e||(e=!0,t=n(...r)),t}}export{n as once}; +" +`; + +exports[`Run config compile-dep-when-es5-rolldown > dist structure 1`] = ` +{ + "files": [ + { + "name": "compile-dep-when-es5.esm.es2017.production.js", + }, + { + "name": "compile-dep-when-es5.esm.es5.production.js", + }, + ], + "name": "dist", +} +`; + +exports[`Run config compile-dep-when-es5-rolldown > file content dist/compile-dep-when-es5.esm.es5.production.js 1`] = ` +"function e(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n file content dist/compile-dep-when-es5.esm.es2017.production.js 1`] = `"function e(e){let t=!1,n;return function(...r){return t||(t=!0,n=e(...r)),n}}export{e as once};"`; + exports[`Run config default-no-venders > dist structure 1`] = ` { "files": [ diff --git a/tests/integration/bundle-dep/index.test.ts b/tests/integration/bundle-dep/index.test.ts index 010275e8..3b8da68d 100644 --- a/tests/integration/bundle-dep/index.test.ts +++ b/tests/integration/bundle-dep/index.test.ts @@ -83,6 +83,21 @@ const tests: ProjectTestUserConfig[] = [ }, engine: ['rollup', 'rolldown'], }, + { + name: 'compile-dep-when-es5', + config: { + entry: './src/compile-dep-when-es5.ts', + transform: { + formats: [], + }, + bundle: { + formats: ['esm', 'es2017'], + codeSplitting: false, + }, + }, + snapshot: 'full', + engine: ['rollup', 'rolldown'], + }, ]; runProjectTest( diff --git a/tests/integration/bundle-dep/src/compile-dep-when-es5.ts b/tests/integration/bundle-dep/src/compile-dep-when-es5.ts new file mode 100644 index 00000000..981cf0f0 --- /dev/null +++ b/tests/integration/bundle-dep/src/compile-dep-when-es5.ts @@ -0,0 +1,4 @@ +import { once } from 'es-toolkit'; + +// once has spread operation should transform to es5 +export { once }; diff --git a/tests/integration/mix-cjs-mjs/__snapshots__/index.test.ts.snap b/tests/integration/mix-cjs-mjs/__snapshots__/index.test.ts.snap index 4851f6e8..bc478026 100644 --- a/tests/integration/mix-cjs-mjs/__snapshots__/index.test.ts.snap +++ b/tests/integration/mix-cjs-mjs/__snapshots__/index.test.ts.snap @@ -493,33 +493,30 @@ exports[`Run config swc-helpers-rolldown > file content dist/entry-mts.cjs.es5.p //#region \\0rolldown/runtime.js var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); //#endregion +let _swc_helpers____object_spread = require("@swc/helpers/_/_object_spread"); //#region src/cjs.js var require_cjs = /* @__PURE__ */ __commonJSMin(((exports, module) => { + var _object_spread$2 = require("@swc/helpers/_/_object_spread"); module.exports.add = function(a, b) { return a + b; }; module.exports.extend = function(a, b) { - return { - ...a, - ...b - }; + return _object_spread$2._({}, a, b); }; })); //#endregion //#region src/cts-file.cts var require_cts_file = /* @__PURE__ */ __commonJSMin(((exports, module) => { - module.exports.ctsFile = (options) => { - return { - type: "ctsFile", - ...options - }; + var _object_spread$1 = require("@swc/helpers/_/_object_spread"); + module.exports.ctsFile = function(options) { + return _object_spread$1._({ type: "ctsFile" }, options); }; })); //#endregion //#region src/entry-mts.ts var import_cjs = require_cjs(); var import_cts_file = require_cts_file(); -const foo = { ...(0, import_cjs.extend)({ a: 1 }, { b: 2 }) }; +var foo = (0, _swc_helpers____object_spread._)({}, (0, import_cjs.extend)({ a: 1 }, { b: 2 })); //#endregion exports.add = import_cjs.add; exports.ctsFile = import_cts_file.ctsFile; @@ -529,36 +526,35 @@ exports.foo = foo; `; exports[`Run config swc-helpers-rolldown > file content dist/entry-mts.esm.es5.production.js 1`] = ` -"//#region \\0rolldown/runtime.js +"import { createRequire } from "node:module"; +import { _ } from "@swc/helpers/_/_object_spread"; +//#region \\0rolldown/runtime.js var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); +var __require = /* @__PURE__ */ createRequire(import.meta.url); //#endregion //#region src/cjs.js var require_cjs = /* @__PURE__ */ __commonJSMin(((exports, module) => { + var _object_spread$1 = __require("@swc/helpers/_/_object_spread"); module.exports.add = function(a, b) { return a + b; }; module.exports.extend = function(a, b) { - return { - ...a, - ...b - }; + return _object_spread$1._({}, a, b); }; })); //#endregion //#region src/cts-file.cts var require_cts_file = /* @__PURE__ */ __commonJSMin(((exports, module) => { - module.exports.ctsFile = (options) => { - return { - type: "ctsFile", - ...options - }; + var _object_spread = __require("@swc/helpers/_/_object_spread"); + module.exports.ctsFile = function(options) { + return _object_spread._({ type: "ctsFile" }, options); }; })); //#endregion //#region src/entry-mts.ts var import_cjs = require_cjs(); var import_cts_file = require_cts_file(); -const foo = { ...(0, import_cjs.extend)({ a: 1 }, { b: 2 }) }; +var foo = _({}, (0, import_cjs.extend)({ a: 1 }, { b: 2 })); //#endregion var add = import_cjs.add; var ctsFile = import_cts_file.ctsFile; @@ -569,39 +565,35 @@ export { add, ctsFile, extend, foo }; exports[`Run config swc-helpers-rolldown > file content dist/entry-mts.umd.es5.production.js 1`] = ` "(function(global, factory) { - typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@ice/pkg-tests-mix-cjs-mjs"] = {})); -})(this, function(exports) { + typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@swc/helpers/_/_object_spread")) : typeof define === "function" && define.amd ? define(["exports", "@swc/helpers/_/_object_spread"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@ice/pkg-tests-mix-cjs-mjs"] = {}, global._swc_helpers____object_spread)); +})(this, function(exports, _swc_helpers____object_spread) { Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); //#region \\0rolldown/runtime.js var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports); //#endregion //#region src/cjs.js var require_cjs = /* @__PURE__ */ __commonJSMin(((exports, module) => { + var _object_spread$2 = require("@swc/helpers/_/_object_spread"); module.exports.add = function(a, b) { return a + b; }; module.exports.extend = function(a, b) { - return { - ...a, - ...b - }; + return _object_spread$2._({}, a, b); }; })); //#endregion //#region src/cts-file.cts var require_cts_file = /* @__PURE__ */ __commonJSMin(((exports, module) => { - module.exports.ctsFile = (options) => { - return { - type: "ctsFile", - ...options - }; + var _object_spread$1 = require("@swc/helpers/_/_object_spread"); + module.exports.ctsFile = function(options) { + return _object_spread$1._({ type: "ctsFile" }, options); }; })); //#endregion //#region src/entry-mts.ts var import_cjs = require_cjs(); var import_cts_file = require_cts_file(); - const foo = { ...(0, import_cjs.extend)({ a: 1 }, { b: 2 }) }; + var foo = (0, _swc_helpers____object_spread._)({}, (0, import_cjs.extend)({ a: 1 }, { b: 2 })); //#endregion exports.add = import_cjs.add; exports.ctsFile = import_cts_file.ctsFile; diff --git a/tests/integration/react/__snapshots__/index.test.ts.snap b/tests/integration/react/__snapshots__/index.test.ts.snap index 01ca7bf8..d7af319c 100644 --- a/tests/integration/react/__snapshots__/index.test.ts.snap +++ b/tests/integration/react/__snapshots__/index.test.ts.snap @@ -123,4 +123,4 @@ exports[`Run config rolldown > dist structure 1`] = ` } `; -exports[`Run config rolldown > file content dist/index.esm.es2017.production.js 1`] = `"import"react";import{jsx as e}from"@ice/jsx-runtime/jsx-runtime";var t=()=>e(\`div\`,{className:\`common-class-name\`,children:\`Hello World\`});export{t as default};"`; +exports[`Run config rolldown > file content dist/index.esm.es2017.production.js 1`] = `"import"react";import{jsx as e}from"@ice/jsx-runtime/jsx-runtime";function t(e){"@babel/helpers - typeof";return t=typeof Symbol==\`function\`&&typeof Symbol.iterator==\`symbol\`?function(e){return typeof e}:function(e){return e&&typeof Symbol==\`function\`&&e.constructor===Symbol&&e!==Symbol.prototype?\`symbol\`:typeof e},t(e)}function n(e,n){if(t(e)!=\`object\`||!e)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var i=r.call(e,n||\`default\`);if(t(i)!=\`object\`)return i;throw TypeError(\`@@toPrimitive must return a primitive value.\`)}return(n===\`string\`?String:Number)(e)}function r(e){var r=n(e,\`string\`);return t(r)==\`symbol\`?r:r+\`\`}function i(e,t,n){return(t=r(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function o(e){for(var t=1;te(\`div\`,o(o({},{className:\`common-class-name\`}),{},{children:\`Hello World\`}));export{s as default};"`;