Fix styled-jsx types when package is not hoisted (#37902)

This ensures we expose the `styled-jsx` types correctly even when the package is not hoisted from next's `node_modules` e.g. when using `pnpm`. We had an existing test that covered this although it installed `styled-jsx` at the top-level as a workaround so the test has been updated to remove this workaround. 

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

Fixes: https://github.com/vercel/next.js/pull/37828#discussion_r901164193
This commit is contained in:
JJ Kasper 2022-06-22 07:09:22 -05:00 committed by GitHub
parent a4117c94b0
commit c4dc081e70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 3 deletions

View file

@ -20,7 +20,6 @@
"@formatjs/cli": "4.2.31", "@formatjs/cli": "4.2.31",
"@types/node": "16.6.2", "@types/node": "16.6.2",
"@types/react": "17.0.19", "@types/react": "17.0.19",
"@types/styled-jsx": "3.4.4",
"babel-plugin-formatjs": "10.3.5", "babel-plugin-formatjs": "10.3.5",
"eslint-plugin-formatjs": "2.17.4", "eslint-plugin-formatjs": "2.17.4",
"typescript": "4.3.5" "typescript": "4.3.5"

View file

@ -30,6 +30,8 @@ export async function writeAppTypeDeclarations(
const content = const content =
'/// <reference types="next" />' + '/// <reference types="next" />' +
eol + eol +
'/// <reference types="next/dist/styled-jsx-types/global" />' +
eol +
(imageImportsEnabled (imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + eol ? '/// <reference types="next/image-types/global" />' + eol
: '') + : '') +

View file

@ -40,6 +40,38 @@ export async function copy_regenerator_runtime(task, opts) {
.target('compiled/regenerator-runtime') .target('compiled/regenerator-runtime')
} }
// eslint-disable-next-line camelcase
export async function copy_styled_jsx_types(task, opts) {
// we copy the styled-jsx types so that we can reference them
// in the next-env.d.ts file so it doesn't matter if the styled-jsx
// package is hoisted out of Next.js' node_modules or not
const styledJsxPath = dirname(require.resolve('styled-jsx/package.json'))
const typeFiles = glob.sync('*.d.ts', { cwd: styledJsxPath })
const outputDir = join(__dirname, 'dist/styled-jsx-types')
let typeReferences = ``
await fs.ensureDir(outputDir)
for (const file of typeFiles) {
const fileNoExt = file.replace(/\.d\.ts/, '')
const content = await fs.readFile(join(styledJsxPath, file), 'utf8')
const exportsIndex = content.indexOf('export')
await fs.writeFile(
join(outputDir, file),
`${content.substring(0, exportsIndex)}\n` +
`declare module 'styled-jsx${
file === 'index.d.ts' ? '' : '/' + fileNoExt
}' {
${content.substring(exportsIndex)}
}`
)
typeReferences += `/// <reference types="./${fileNoExt}" />\n`
}
await fs.writeFile(join(outputDir, 'global.d.ts'), typeReferences)
}
const externals = { const externals = {
// don't bundle caniuse-lite data so users can // don't bundle caniuse-lite data so users can
// update it manually // update it manually
@ -1803,6 +1835,7 @@ export async function compile(task, opts) {
// we compile this each time so that fresh runtime data is pulled // we compile this each time so that fresh runtime data is pulled
// before each publish // before each publish
'ncc_amp_optimizer', 'ncc_amp_optimizer',
'copy_styled_jsx_types',
], ],
opts opts
) )

View file

@ -1,7 +1,6 @@
/// <reference types="node" /> /// <reference types="node" />
/// <reference types="react" /> /// <reference types="react" />
/// <reference types="react-dom" /> /// <reference types="react-dom" />
/// <reference types="styled-jsx" />
import React from 'react' import React from 'react'
import { ParsedUrlQuery } from 'querystring' import { ParsedUrlQuery } from 'querystring'

View file

@ -28,7 +28,6 @@ describe('TypeScript basic', () => {
'@types/node': 'latest', '@types/node': 'latest',
'@types/react': 'latest', '@types/react': 'latest',
'@types/react-dom': 'latest', '@types/react-dom': 'latest',
'styled-jsx': 'latest',
}, },
}) })
}) })

View file

@ -16,6 +16,8 @@ describe('find config', () => {
const content = const content =
'/// <reference types="next" />' + '/// <reference types="next" />' +
eol + eol +
'/// <reference types="next/dist/styled-jsx-types/global" />' +
eol +
(imageImportsEnabled (imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + eol ? '/// <reference types="next/image-types/global" />' + eol
: '') + : '') +
@ -37,6 +39,8 @@ describe('find config', () => {
const content = const content =
'/// <reference types="next" />' + '/// <reference types="next" />' +
eol + eol +
'/// <reference types="next/dist/styled-jsx-types/global" />' +
eol +
(imageImportsEnabled (imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + eol ? '/// <reference types="next/image-types/global" />' + eol
: '') + : '') +
@ -58,6 +62,8 @@ describe('find config', () => {
const content = const content =
'/// <reference types="next" />' + '/// <reference types="next" />' +
eol + eol +
'/// <reference types="next/dist/styled-jsx-types/global" />' +
eol +
(imageImportsEnabled (imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + eol ? '/// <reference types="next/image-types/global" />' + eol
: '') + : '') +