Skip to content

Commit

Permalink
Add support for tsconfig 'nodenext' | 'node16' (#44177)
Browse files Browse the repository at this point in the history
## ESM: support module option for tsconfig.json 

- fixes #37525
- fixes #41961

With [TypeScript 4.7 providing ECMAScript Module Support](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#ecmascript-module-support-in-node-js), we can now set this in our tsconfig.json file for the [module](https://www.typescriptlang.org/tsconfig#module) option.

Webpack added "extensionAlias" to solve importing ts files with .js extension -> webpack/enhanced-resolve#351



Co-authored-by: JJ Kasper <[email protected]>
  • Loading branch information
loettz and ijjk committed Jan 28, 2023
1 parent b4c80c9 commit 67468f9
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/next/src/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,9 @@ export default async function getBaseWebpackConfig(
extensions: isNodeServer
? ['.js', '.mjs', '.tsx', '.ts', '.jsx', '.json', '.wasm']
: ['.mjs', '.js', '.tsx', '.ts', '.jsx', '.json', '.wasm'],
extensionAlias: {
'.js': ['.ts', '.tsx', '.js', '.jsx'],
},
modules: [
'node_modules',
...nodePathList, // Support for NODE_PATH environment variable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ function getDesiredCompilerOptions(
ts.ModuleKind.ESNext,
ts.ModuleKind.CommonJS,
ts.ModuleKind.AMD,
ts.ModuleKind.NodeNext,
ts.ModuleKind.Node16,
],
value: 'esnext',
reason: 'for dynamic import() support',
Expand Down
49 changes: 49 additions & 0 deletions test/integration/tsconfig-verifier/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,55 @@ describe('tsconfig.json verifier', () => {
`)
})

it('allows you to set node16 module mode', async () => {
expect(await exists(tsConfig)).toBe(false)

await writeFile(
tsConfig,
`{ "compilerOptions": { "esModuleInterop": false, "module": "node16", "moduleResolution": "node16" } }`
)
await new Promise((resolve) => setTimeout(resolve, 500))
const { code, stderr, stdout } = await nextBuild(appDir, undefined, {
stderr: true,
stdout: true,
})
expect(stderr + stdout).not.toContain('moduleResolution')
expect(code).toBe(0)

expect(await readFile(tsConfig, 'utf8')).toMatchInlineSnapshot(`
"{
\\"compilerOptions\\": {
\\"esModuleInterop\\": true,
\\"module\\": \\"node16\\",
\\"moduleResolution\\": \\"node16\\",
\\"lib\\": [
\\"dom\\",
\\"dom.iterable\\",
\\"esnext\\"
],
\\"allowJs\\": true,
\\"skipLibCheck\\": true,
\\"strict\\": false,
\\"forceConsistentCasingInFileNames\\": true,
\\"noEmit\\": true,
\\"incremental\\": true,
\\"resolveJsonModule\\": true,
\\"isolatedModules\\": true,
\\"jsx\\": \\"preserve\\"
},
\\"include\\": [
\\"next-env.d.ts\\",
\\"**/*.ts\\",
\\"**/*.tsx\\"
],
\\"exclude\\": [
\\"node_modules\\"
]
}
"
`)
})

it('allows you to extend another configuration file', async () => {
expect(await exists(tsConfig)).toBe(false)
expect(await exists(tsConfigBase)).toBe(false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react'

export function TsxComponent() {
return <>import me</>
}
5 changes: 5 additions & 0 deletions test/integration/webpack-config-extensionalias/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
webpack(config) {
return config
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// import tsx file with .js extension alias, this leads to a build fail if extensionAlias is not configured
import { TsxComponent } from '../components/TsxComponent.js'
export default function PageWithImport() {
return (
<>
See import here: <TsxComponent />
</>
)
}
12 changes: 12 additions & 0 deletions test/integration/webpack-config-extensionalias/test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { join } from 'path'
import { nextBuild } from 'next-test-utils'

const appDir = join(__dirname, '../')

describe('webpack config with extensionAlias setting', () => {
it('should run correctly with an tsx file import with .js extension', async () => {
const { code } = await nextBuild(appDir, [], {})

expect(code).toBe(0)
})
})

0 comments on commit 67468f9

Please sign in to comment.