From f673170cf62daf117a59be4d5dd923be06223a3f Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Sat, 4 Feb 2023 10:56:18 +0800 Subject: [PATCH 1/4] Support 'exports' field in package.json of published modules. --- src/transpilation/resolve.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index c7ea38dd1..fa0a5200a 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -15,6 +15,7 @@ const resolver = resolve.ResolverFactory.createResolver({ enforceExtension: true, // Resolved file must be a lua file fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, useSyncFileSystemCalls: true, + conditionNames: ["require", "node", "default"], symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection) }); From 59497107973996ddb6a10c7fba3a55827304321e Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Sat, 4 Feb 2023 13:11:32 +0800 Subject: [PATCH 2/4] add exports field test --- .eslintignore | 3 +- .gitignore | 2 + .prettierignore | 2 + test/transpile/module-resolution.spec.ts | 44 +++++++++++++++++++ .../app/main.ts | 5 +++ .../app/package-lock.json | 28 ++++++++++++ .../app/package.json | 7 +++ .../app/tsconfig.json | 6 +++ .../dependency1-ts/package.json | 14 ++++++ .../dependency1-ts/src/d1otherfile.ts | 3 ++ .../dependency1-ts/src/index.ts | 10 +++++ .../dependency1-ts/tsconfig.json | 13 ++++++ 12 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json diff --git a/.eslintignore b/.eslintignore index 492195f96..a1a50129e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,5 +3,6 @@ /test/cli/errors /test/cli/watch /test/transpile/directories -/test/transpile/module-resolution/*/node_modules +/test/transpile/module-resolution/**/node_modules +/test/transpile/module-resolution/**/dist /test/transpile/outFile diff --git a/.gitignore b/.gitignore index e9fe7f092..fc3920330 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ node_modules /dist /coverage +/test/transpile/module-resolution/**/dist +/test/transpile/module-resolution/**/tsconfig.tsbuildinfo yarn.lock .vscode diff --git a/.prettierignore b/.prettierignore index 23b85e3bd..656f1a4d6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,5 @@ /coverage /test/translation/transformation/characterEscapeSequence.ts /benchmark/dist +/test/transpile/module-resolution/**/node_modules +/test/transpile/module-resolution/**/dist diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 8f8cc0230..ed2918eb7 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -5,6 +5,7 @@ import * as ts from "typescript"; import { BuildMode } from "../../src"; import { normalizeSlashes } from "../../src/utils"; import { pathsWithoutBaseUrl } from "../../src/transpilation/diagnostics"; +import { execSync } from "child_process"; describe("basic module resolution", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); @@ -272,6 +273,49 @@ describe("module resolution project with dependencies built by tstl library mode }); }); +describe("module resolution project with dependencies built by tstl library mode and has exports field", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-has-exports-field"); + const appPath = path.join(projectPath, "app"); + + // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow + tstl.transpileProject(path.join(projectPath, "dependency1-ts", "tsconfig.json")); + + // Install dependencies. This will create node_modules folder with dependency1-ts in it. + execSync("npm i", { cwd: appPath }); + + const expectedResult = { + dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", + dependency1OtherFileFuncResult: "dependency1OtherFileFunc in dependency1/d1otherfile", + }; + + test("can resolve lua dependencies", () => { + const transpileResult = util + .testProject(path.join(appPath, "tsconfig.json")) + .setMainFileName(path.join(appPath, "main.ts")) + .setOptions({ outDir: "tstl-out", moduleResolution: ts.ModuleResolutionKind.Node16 }) + .expectToEqual(expectedResult) + .getLuaResult(); + + // Assert node_modules file requires the correct lualib_bundle + const requiringLuaFile = path.join("lua_modules", "dependency1", "dist", "index.lua"); + const lualibRequiringFile = transpileResult.transpiledFiles.find(f => f.outPath.endsWith(requiringLuaFile)); + expect(lualibRequiringFile).toBeDefined(); + expect(lualibRequiringFile?.lua).toContain('require("lualib_bundle")'); + }); + + test("can resolve dependencies and bundle", () => { + const mainFile = path.join(appPath, "main.ts"); + util.testProject(path.join(appPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ + luaBundle: "bundle.lua", + luaBundleEntry: mainFile, + moduleResolution: ts.ModuleResolutionKind.Node16, + }) + .expectToEqual(expectedResult); + }); +}); + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1037 describe("module resolution with tsx", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tsx"); diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts new file mode 100644 index 000000000..3421911f2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts @@ -0,0 +1,5 @@ +import { dependency1IndexFunc } from "dependency1/sub"; +import { dependency1OtherFileFunc } from "dependency1/sub/d1otherfile"; + +export const dependency1IndexResult = dependency1IndexFunc(); +export const dependency1OtherFileFuncResult = dependency1OtherFileFunc(); diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json new file mode 100644 index 000000000..3922eb8c4 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json @@ -0,0 +1,28 @@ +{ + "name": "app", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "app", + "version": "0.0.1", + "dependencies": { + "dependency1": "file:../dependency1-ts" + } + }, + "../dependency1-ts": { + "name": "dependency1", + "version": "0.0.1" + }, + "node_modules/dependency1": { + "resolved": "../dependency1-ts", + "link": true + } + }, + "dependencies": { + "dependency1": { + "version": "file:../dependency1-ts" + } + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json new file mode 100644 index 000000000..b88dc4bc0 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json @@ -0,0 +1,7 @@ +{ + "name": "app", + "version": "0.0.1", + "dependencies": { + "dependency1": "file:../dependency1-ts" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json new file mode 100644 index 000000000..7b0969155 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "moduleResolution": "node16" + }, + "references": [{ "path": "./node_modules/dependency1" }] +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json new file mode 100644 index 000000000..c74b862a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json @@ -0,0 +1,14 @@ +{ + "name": "dependency1", + "version": "0.0.1", + "exports": { + "./sub": { + "require": "./dist/index", + "types": "./dist/index.d.ts" + }, + "./sub/*": { + "require": "./dist/*", + "types": "./dist/*.d.ts" + } + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts new file mode 100644 index 000000000..3877a1c52 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts @@ -0,0 +1,3 @@ +export function dependency1OtherFileFunc() { + return "dependency1OtherFileFunc in dependency1/d1otherfile"; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts new file mode 100644 index 000000000..03cff47c5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts @@ -0,0 +1,10 @@ +import { dependency1OtherFileFunc } from "./d1otherfile"; + +export function dependency1IndexFunc() { + return "function in dependency 1 index: " + dependency1OtherFileFunc(); +} + +export function squares(nums: number[]) { + // Require lualib functionality + return nums.map(n => n * n); +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json new file mode 100644 index 000000000..d6ffcdc0c --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "composite": true + }, + "tstl": { + "buildMode": "library" + } +} From cae75e2242e619099e69ec227602b3a01ea552be Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Sun, 5 Feb 2023 21:54:02 +0800 Subject: [PATCH 3/4] use fs symlink during test --- test/transpile/module-resolution.spec.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index ed2918eb7..f9e1894d5 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -2,10 +2,10 @@ import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import * as ts from "typescript"; +import * as fs from "fs-extra"; import { BuildMode } from "../../src"; import { normalizeSlashes } from "../../src/utils"; import { pathsWithoutBaseUrl } from "../../src/transpilation/diagnostics"; -import { execSync } from "child_process"; describe("basic module resolution", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); @@ -278,10 +278,13 @@ describe("module resolution project with dependencies built by tstl library mode const appPath = path.join(projectPath, "app"); // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow - tstl.transpileProject(path.join(projectPath, "dependency1-ts", "tsconfig.json")); + const dependency1Path = path.join(projectPath, "dependency1-ts"); + tstl.transpileProject(path.join(dependency1Path, "tsconfig.json")); // Install dependencies. This will create node_modules folder with dependency1-ts in it. - execSync("npm i", { cwd: appPath }); + const nodeModulesPath = path.join(appPath, "node_modules"); + fs.ensureDirSync(nodeModulesPath); + fs.ensureSymlinkSync(dependency1Path, path.join(nodeModulesPath, "dependency1"), "dir"); const expectedResult = { dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", From 426692a23b68cdb3bb2eb133df7a41b186b61f13 Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Sun, 5 Feb 2023 23:06:43 +0800 Subject: [PATCH 4/4] remove package-lock in test --- .../app/package-lock.json | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json deleted file mode 100644 index 3922eb8c4..000000000 --- a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package-lock.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "app", - "version": "0.0.1", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "app", - "version": "0.0.1", - "dependencies": { - "dependency1": "file:../dependency1-ts" - } - }, - "../dependency1-ts": { - "name": "dependency1", - "version": "0.0.1" - }, - "node_modules/dependency1": { - "resolved": "../dependency1-ts", - "link": true - } - }, - "dependencies": { - "dependency1": { - "version": "file:../dependency1-ts" - } - } -}