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

ESM build error on directory imports after upgrade to TS 5.0.0@beta #434

Closed
bluebill1049 opened this issue Jan 26, 2023 · 4 comments
Closed
Labels
kind: support Asking for support with something or a specific use case topic: TS version Related to a change in a TS version

Comments

@bluebill1049
Copy link

bluebill1049 commented Jan 26, 2023

Troubleshooting

  1. Does tsc have the same output? If so, please explain why this is incorrect behavior

    It's working correctly with tsc

  2. Does your Rollup plugin order match? If not, please elaborate

    Rollup config hasn't been changed for years and looks like the order is not an issue:
    https://github.com/react-hook-form/react-hook-form/blob/master/scripts/rollup/createRollupConfig.js#L14-L44

  3. Can you create a minimal example that reproduces this behavior? Preferably, use this environment for your reproduction

    Here is the PR: 🦶 upgrade to TS 5.0.0 react-hook-form/react-hook-form#9834

What happens and why it is incorrect

Related to export *

> [email protected] build:esm /home/runner/work/react-hook-form/react-hook-form
> rollup -c ./scripts/rollup/rollup.esm.config.js


src/index.ts → dist/index.esm.mjs...
[!] (plugin rpt2) Error: src/index.ts:2:15 - error TS2792: Cannot find module './logic'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?

2 export * from './logic';
                ~~~~~~~~~
src/index.ts:3:15 - error TS2792: Cannot find module './types'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?

3 export * from './types';
                ~~~~~~~~~
src/index.ts:10:15 - error TS2792: Cannot find module './utils'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?

10 export * from './utils';
                 ~~~~~~~~~

src/index.ts

    at error (/home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:19[8](https://github.com/react-hook-form/react-hook-form/actions/runs/4019858069/jobs/6907177794#step:6:9):30)
    at throwPluginError (/home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected][9](https://github.com/react-hook-form/react-hook-form/actions/runs/4019858069/jobs/6907177794#step:6:10).1/node_modules/rollup/dist/shared/rollup.js:21718:12)
    at Object.error (/home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:22672:20)
    at RollupContext.error (/home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected]_xena5liww6ngah7udrne4zlxbq/node_modules/rollup-plugin-typescript2/src/context.ts:35:17)
    at /home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected]_xena5liww6ngah7udrne4zlxbq/node_modules/rollup-plugin-typescript2/src/diagnostics.ts:70:17
    at Array.forEach (<anonymous>)
    at printDiagnostics (/home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected]_xena5liww6ngah7udrne4zlxbq/node_modules/rollup-plugin-typescript2/src/diagnostics.ts:42:14)
    at typecheckFile (/home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected]_xena5liww6ngah7udrne4zlxbq/node_modules/rollup-plugin-typescript2/src/index.ts:67:3)
    at Object.<anonymous> (/home/runner/work/react-hook-form/react-hook-form/node_modules/.pnpm/[email protected]_xena5liww6ngah7udrne4zlxbq/node_modules/rollup-plugin-typescript2/src/index.ts:257:5)
    at Generator.next (<anonymous>)

Environment

Github action and local build

Versions

  System:
    OS: macOS 13.0
    CPU: (8) arm64 Apple M1
    Memory: 63.31 MB / 8.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 18.5.0 - ~/.nvm/versions/node/v18.5.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.5.0/bin/yarn
    npm: 8.12.1 - ~/.nvm/versions/node/v18.5.0/bin/npm
  npmPackages:
    rollup: ^2.79.1 => 2.79.1 
    rollup-plugin-typescript2: ^0.34.1 => 0.34.1 
    typescript: 5.0.0-beta => 5.0.0-beta 

rollup.config.js

:
  const config = {
    input: options.input,
    output: {
      file: outputName,
      format: options.format,
      name: 'ReactHookForm',
      sourcemap: true,
      globals: { react: 'React' },
      exports: 'named',
    },
    plugins: [
      external(),
      typescript({
        tsconfig: options.tsconfig,
        clean: true,
        exclude: ['**/__tests__', '**/*.test.ts'],
      }),
      options.format === 'umd' &&
        commonjs({
          include: /\/node_modules\//,
        }),
      sourcemaps(),
      options.format !== 'esm' &&
        terser({
          output: { comments: false },
          compress: {
            drop_console: true,
          },
        }),
    ].filter(Boolean),
  };

tsconfig.json

:
{
  "compilerOptions": {
    "sourceMap": true,
    "module": "es2015",
    "target": "es2018",
    "moduleResolution": "node",
    "outDir": "./dist",
    "jsx": "react",
    "skipLibCheck": true,
    "declaration": true,
    "declarationMap": true,
    "noEmit": true,
    "esModuleInterop": true,
    "lib": ["dom", "dom.iterable", "esnext"],
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"],
  "exclude": [
    "node_modules",
    "app",
    "examples",
    "cypress",
    "src/*.test.ts",
    "src/*.test.tsx",
    "src/*.test-d.ts",
    "src/*.test-d.tsx",
    "src/__mocks__"
  ]
}

package.json

:
{
  "name": "react-hook-form",
  "description": "Performant, flexible and extensible forms library for React Hooks",
  "version": "7.42.1",
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.mjs",
  "umd:main": "dist/index.umd.js",
  "unpkg": "dist/index.umd.js",
  "jsdelivr": "dist/index.umd.js",
  "jsnext:main": "dist/index.esm.mjs",
  "source": "src/index.ts",
  "types": "dist/index.d.ts",
  "sideEffects": false,
  "files": [
    "dist",
    "dist/__tests__"
  ],
  "exports": {
    "./package.json": "./package.json",
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.esm.mjs",
      "require": "./dist/index.cjs.js"
    }
  },
  "scripts": {
    "clean": "rimraf dist",
    "prebuild": "pnpm clean",
    "build": "pnpm build:modern",
    "build:watch": "pnpm build:modern -w",
    "postbuild": "rimraf dist/__tests__ && node ./scripts/rollup/assert-esm-exports.mjs && node ./scripts/rollup/assert-cjs-exports.cjs",
    "build:modern": "rollup -c ./scripts/rollup/rollup.config.js",
    "build:esm": "rollup -c ./scripts/rollup/rollup.esm.config.js",
    "prettier:fix": "prettier --config .prettierrc --write \"**/*.{js,ts,tsx,css}\"",
    "lint": "eslint '**/*.{js,ts,tsx}'",
    "lint:fix": "pnpm lint --fix",
    "type": "tsc --noEmit",
    "jest-preview": "jest-preview",
    "test": "jest --config ./scripts/jest/jest.config.js",
    "test:coverage": "pnpm test -- --coverage",
    "test:watch": "pnpm test -- --onlyChanged --watch",
    "test:web": "TEST_ENV=web pnpm test",
    "test:type": "tsd src/__typetest__",
    "e2e": "cypress run",
    "e2e:watch": "cypress open",
    "api-extractor": "api-extractor run --local",
    "api-extractor:build": "pnpm build:esm && pnpm api-extractor",
    "api-extractor:ci": "node scripts/apiExtractor.js",
    "postversion": "git push && git push origin v$npm_package_version",
    "prepublishOnly": "pnpm install && pnpm lint:fix && pnpm type && pnpm test && pnpm build",
    "bundlewatch": "pnpm build:modern && bundlewatch",
    "start": "pnpm build:esm && pnpm --dir ./app install && pnpm --dir ./app run dev"
  },
  "keywords": [
    "react",
    "hooks",
    "form",
    "forms",
    "form-validation",
    "validation",
    "typescript",
    "react-hooks"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/react-hook-form/react-hook-form"
  },
  "homepage": "https://www.react-hook-form.com",
  "author": "<[email protected]>",
  "license": "MIT",
  "devDependencies": {
    "@microsoft/api-extractor": "^7.33.7",
    "@rollup/plugin-commonjs": "^22.0.2",
    "@rollup/plugin-node-resolve": "^14.1.0",
    "@swc/core": "^1.3.25",
    "@swc/jest": "^0.2.24",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/react-hooks": "^8.0.1",
    "@types/jest": "^29.2.5",
    "@types/react": "^18.0.26",
    "@types/react-dom": "^18.0.10",
    "@types/testing-library__jest-dom": "^5.14.5",
    "@typescript-eslint/eslint-plugin": "^5.48.1",
    "@typescript-eslint/parser": "^5.48.1",
    "bundlewatch": "^0.3.3",
    "cypress": "10.9.0",
    "eslint": "^8.31.0",
    "eslint-config-prettier": "^8.6.0",
    "eslint-plugin-cypress": "^2.12.1",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-react": "^7.31.11",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-simple-import-sort": "^8.0.0",
    "husky": "^8.0.3",
    "jest": "^29.3.1",
    "jest-environment-jsdom": "^29.3.1",
    "jest-preview": "^0.3.1",
    "jest-watch-typeahead": "^2.2.1",
    "lint-staged": "^13.1.0",
    "prettier": "^2.8.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-test-renderer": "^18.2.0",
    "rimraf": "^3.0.2",
    "rollup": "^2.79.1",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-sourcemaps": "^0.6.3",
    "rollup-plugin-terser": "^7.0.2",
    "rollup-plugin-typescript2": "^0.34.1",
    "tsd": "^0.25.0",
    "typescript": "5.0.0-beta"
  },
  "bundlewatch": {
    "files": [
      {
        "path": "./dist/index.cjs.js",
        "maxSize": "9.2 kB"
      }
    ]
  },
  "peerDependencies": {
    "react": "^16.8.0 || ^17 || ^18"
  },
  "lint-staged": {
    "*.{js,ts,tsx}": [
      "pnpm lint:fix",
      "pnpm prettier:fix"
    ],
    "*.{md,json,yml}": [
      "prettier --write"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "funding": {
    "type": "opencollective",
    "url": "https://opencollective.com/react-hook-form"
  },
  "engines": {
    "node": ">=12.22.0"
  },
  "packageManager": "[email protected]"
}
@agilgur5
Copy link
Collaborator

agilgur5 commented Jan 29, 2023

text > screenshots

Please note that text is strongly preferred over screenshots when reporting GitHub issues (or StackOverflow questions, per the link), as text can be copied, searched, etc and is significantly more accessible, while screenshots cannot / are not nearly as accessible.

As you used a screenshot, I did have to manually transpose the text of the error here:

src/index.ts → dist/index.esm.mjs...
[!] (plugin rpt2) Error: src/index.ts:2:15 - error: TS2792: Cannot find module './logic'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?

2 export * from './logic';

MJS usage

Based on your code, this looks to be because of your usage of MJS, i.e. the ESM spec, along with how TS has changed up resolution in this space in recent times with nodenext / node16 and, as introduced in TS 5.0, bundler.

Specifically, the 3 imports / exports you're getting an error on are all directory imports.

Per the Node ESM docs, directory imports must be fully specified:

Directory indexes (e.g. './startup/index.js') must also be fully specified.

So, as far as I can tell, this actually seems like a bug from when the MJS extension was specified back in react-hook-form/react-hook-form#7262, just that TS / Node just didn't error out on it before, whereas it has a stricter adherence to the spec now.

TS 5.0 support

TS 5.0 is still in beta, so I think we'll want to wait for a stable release before supporting things that might change beforehand.

In particular, rpt2 will probably have to update some code to support the new moduleResolution: "bundler" (as linked above).
nodenext / node16 were going to cause breakage with the Rollup integration, so I hadn't taken the plunge to attempt to implement those, especially as no one requested them, but this new mode is a different story as it is specifically built to be used with bundlers like Rollup.

@agilgur5 agilgur5 added the topic: TS version Related to a change in a TS version label Jan 29, 2023
@agilgur5 agilgur5 changed the title Build error after upgrade to Typescript 5.0.0@beta ESM build error on directory imports after upgrade to Typescript 5.0.0@beta Jan 29, 2023
@agilgur5 agilgur5 changed the title ESM build error on directory imports after upgrade to Typescript 5.0.0@beta ESM build error on directory imports after upgrade to TS 5.0.0@beta Jan 29, 2023
@bluebill1049
Copy link
Author

Please note that text is strongly preferred over screenshots when reporting GitHub issues (or StackOverflow questions, per the link), as text can be copied, searched, etc and is significantly more accessible, while screenshots cannot / are not nearly as accessible.

As you used a screenshot, I did have to manually transpose the text of the error here:

I apologise for that part, which I could have done better.

So, as far as I can tell, this actually seems like a bug from when the MJS extension was specified back in react-hook-form/react-hook-form#7262, just that TS / Node just didn't error out on it before, whereas it has a stricter adherence to the spec now.

Thanks for the information above as well.

@agilgur5
Copy link
Collaborator

agilgur5 commented Jan 29, 2023

You're welcome 👍

I suspect changing those 3 lines to the format of export * from 'logic/index' is probably enough to fix them for your use-case, but please write here if you hit any other discrepancies with the TS 5.0 beta!
It's possible things may have broken in rpt2 due to the upstream changes, but I also suspect other users may hit into similar issues (e.g. spec changes like this one) and find this one helpful.

@agilgur5 agilgur5 added the kind: support Asking for support with something or a specific use case label Jan 29, 2023
@Thiago-Offredi

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: support Asking for support with something or a specific use case topic: TS version Related to a change in a TS version
Projects
None yet
Development

No branches or pull requests

3 participants