diff --git a/buildLib/esbuild-plugin-swc.mjs b/buildLib/esbuild-plugin-swc.mjs index 9b2d5c97..b3ba63e1 100644 --- a/buildLib/esbuild-plugin-swc.mjs +++ b/buildLib/esbuild-plugin-swc.mjs @@ -30,8 +30,31 @@ SOFTWARE. import { transform, transformSync } from '@swc/core'; import path from 'node:path'; -import process from 'node:process'; import fs from 'node:fs/promises'; +import { existsSync } from 'node:fs'; + +function getNodeModulesDirectoryForPath(currentDir){ + let relativePath = "node_modules"; + let resolvedPath = path.resolve(currentDir, relativePath); + + function countSeparators(str) { + let count = 0; + for(let i = 0; i < str.length; i++) { + if(str[i] == path.sep) + count++; + } + return count; + } + + while(!existsSync(resolvedPath)){ + if(countSeparators(resolvedPath) <= 1){ + throw new Error("Could not find node_modules directory"); + } + relativePath = path.join("..", relativePath); + resolvedPath = path.resolve(currentDir, relativePath); + } + return resolvedPath; +} function assignDeep(target, source) { for (const key in source) { @@ -54,7 +77,18 @@ export default function swcPlugin(options, isAsync) { name: 'esbuild:swc', setup(builder) { builder.onResolve({ filter: /\.(m?[tj]s)$/ }, (args) => { - const fullPath = path.resolve(args.resolveDir, args.path); + let fullPath; + let defaultPath = path.resolve(args.resolveDir, args.path); + if(args.kind == 'import-statement'){ + if(existsSync(defaultPath)){ + fullPath = defaultPath; + }else{ + let nodeModulesPath = getNodeModulesDirectoryForPath(args.resolveDir); + fullPath = path.join(nodeModulesPath, args.path); + } + }else{ + fullPath = defaultPath; + } return { path: fullPath, }; diff --git a/esbuild-runner.mjs b/esbuild-runner.mjs index acc65236..1d00b816 100644 --- a/esbuild-runner.mjs +++ b/esbuild-runner.mjs @@ -2,6 +2,7 @@ import * as esbuild from 'esbuild' import Path from 'node:path'; import { createRequire } from 'node:module'; import { existsSync, readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; import semver from 'semver'; @@ -14,7 +15,7 @@ import swcPlugin from './buildLib/esbuild-plugin-swc.mjs'; function getScriptPath(){ try{ - return import.meta.url; + return fileURLToPath(import.meta.url); }catch(e){ return __filename||null; } @@ -22,39 +23,51 @@ function getScriptPath(){ function getScriptDirectory(){ try{ - return Path.dirname(import.meta.url); + return Path.dirname(fileURLToPath(import.meta.url)); }catch(e){ return __dirname||null; } } const resolveFileFromPackage = (function(){ - return ((new Function("try{return import.meta.resolve;}catch(e){return null}"))()||createRequire(getScriptPath()).resolve); + const rawResolve = ((function(){try{return import.meta.resolve;}catch(e){return null}})()||createRequire(getScriptPath()).resolve); + return function(fileToResolve){ + const result = rawResolve(fileToResolve); + if(result.startsWith("file:")){ + return fileURLToPath(result); + } + return result; + }; })(); -function readKeyFromPackageJson(key,pkg) { - let resolvedPath; - if(typeof pkg == "undefined" || pkg == null){ - let currentDir = getScriptDirectory; - let relativePath = "package.json"; - resolvedPath = Path.resolve(currentDir, relativePath); +function getOwnPackageJsonPath(){ + let currentDir = getScriptDirectory(); + let relativePath = "package.json"; + let resolvedPath = Path.resolve(currentDir, relativePath); - function countSeparators(str) { - let count = 0; - for(let i = 0; i < str.length; i++) { - if(str[i] == Path.sep) - count++; - } - return count; + function countSeparators(str) { + let count = 0; + for(let i = 0; i < str.length; i++) { + if(str[i] == Path.sep) + count++; } + return count; + } - while(!existsSync(resolvedPath)){ - if(countSeparators(resolvedPath) <= 1){ - throw new Error("Could not find package.json file"); - } - relativePath = Path.join("..", relativePath); - resolvedPath = Path.resolve(currentDir, relativePath); + while(!existsSync(resolvedPath)){ + if(countSeparators(resolvedPath) <= 1){ + throw new Error("Could not find package.json file"); } + relativePath = Path.join("..", relativePath); + resolvedPath = Path.resolve(currentDir, relativePath); + } + return resolvedPath; +} + +function readKeyFromPackageJson(key,pkg) { + let resolvedPath; + if(typeof pkg == "undefined" || pkg == null){ + resolvedPath = getOwnPackageJsonPath(); }else{ resolvedPath = resolveFileFromPackage(Path.join(pkg,"package.json")); if(!resolvedPath||!existsSync(resolvedPath)){ @@ -233,19 +246,37 @@ async function build(params) { if(!semver.satisfies(installedCoreJsVersion, readKeyFromPackageJson("devDependencies.core-js"))){ throw new Error("Please update your dependencies, the core-js version installed does not match the version specified in the package.json file."); } + + const swcTargets = { + "es2015": { + "chrome": "49", + "firefox": "44", + "safari": "10", + "edge": "13", + "opera": "36", + "android": "125", + "ios": "10" + }, + "compat": compatTargets + }; + swcConfig.env = { "bugfixes": true, "mode": "usage", "coreJs": installedCoreJsVersion }; + swcConfig.env.targets = swcTargets[params.options.target??'es2015']||swcTargets["es2015"]; if(params.options.target == "compat") { - swcConfig.env.targets = compatTargets; swcConfig.jsc.minify.compress.ecma = 3; esbuildTarget = convertToEsbuildTarget(compatTargets); //esbuild does not officialy support es3 but outputs es3 compatable code when you specifiy es5 as the target. esbuildTarget.push("es5"); }else{ - swcConfig.jsc.target = params.options.target??'es2015'; + const ecmaVersion = parseInt((params.options.target??'es2015').slice(2)); + if(isNaN(ecmaVersion)){ + ecmaVersion = 2015; + } + swcConfig.jsc.minify.compress.ecma = ecmaVersion; esbuildTarget = params.options.target??'es2015'; } } diff --git a/package-lock.json b/package-lock.json index 9805eeee..e4746fb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "core-js": "^3.37.1", "esbuild": "^0.21.5", "eslint": "^9.4.0", - "mocha": "^10.4.0" + "mocha": "^10.4.0", + "semver": "^7.6.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -2120,6 +2121,19 @@ } ] }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", diff --git a/package.json b/package.json index 47a4c8dc..7cc35d4e 100644 --- a/package.json +++ b/package.json @@ -48,12 +48,13 @@ "opera": "12.1", "android": "122", "ios": "8", - "node": "6.17.1" + "node": "13.2.0" }, "devDependencies": { "mocha": "^10.4.0", "esbuild": "^0.21.5", "eslint": "^9.4.0", + "semver": "^7.6.2", "core-js": "^3.37.1", "@swc/core": "^1.5.28", "@swc/helpers": "^0.5.11"