Skip to content

Commit

Permalink
fix(importAnalysis): warning on ExportAllDeclaration (#12799)
Browse files Browse the repository at this point in the history
  • Loading branch information
sun0day committed Apr 13, 2023
1 parent 1607f4a commit 5136b9b
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 11 deletions.
77 changes: 70 additions & 7 deletions packages/vite/src/node/__tests__/plugins/import.spec.ts
@@ -1,9 +1,19 @@
import { describe, expect, test } from 'vitest'
import { beforeEach, describe, expect, test, vi } from 'vitest'
import { transformCjsImport } from '../../plugins/importAnalysis'

describe('transformCjsImport', () => {
const url = './node_modules/.vite/deps/react.js'
const rawUrl = 'react'
const config: any = {
command: 'serve',
logger: {
warn: vi.fn(),
},
}

beforeEach(() => {
config.logger.warn.mockClear()
})

test('import specifier', () => {
expect(
Expand All @@ -12,6 +22,8 @@ describe('transformCjsImport', () => {
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
Expand All @@ -22,7 +34,14 @@ describe('transformCjsImport', () => {

test('import default specifier', () => {
expect(
transformCjsImport('import React from "react"', url, rawUrl, 0),
transformCjsImport(
'import React from "react"',
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
'const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react',
Expand All @@ -34,6 +53,8 @@ describe('transformCjsImport', () => {
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
Expand All @@ -43,21 +64,48 @@ describe('transformCjsImport', () => {

test('import all specifier', () => {
expect(
transformCjsImport('import * as react from "react"', url, rawUrl, 0),
transformCjsImport(
'import * as react from "react"',
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
'const react = __vite__cjsImport0_react',
)
})

test('export all specifier', () => {
expect(transformCjsImport('export * from "react"', url, rawUrl, 0)).toBe(
undefined,
expect(
transformCjsImport(
'export * from "react"',
url,
rawUrl,
0,
'modA',
config,
),
).toBe(undefined)

expect(config.logger.warn).toBeCalledWith(
expect.stringContaining(`export * from "react"\` in modA`),
)

expect(
transformCjsImport('export * as react from "react"', url, rawUrl, 0),
transformCjsImport(
'export * as react from "react"',
url,
rawUrl,
0,
'',
config,
),
).toBe(undefined)

expect(config.logger.warn).toBeCalledTimes(1)
})

test('export name specifier', () => {
Expand All @@ -67,6 +115,8 @@ describe('transformCjsImport', () => {
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
Expand All @@ -81,6 +131,8 @@ describe('transformCjsImport', () => {
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
Expand All @@ -92,7 +144,14 @@ describe('transformCjsImport', () => {

test('export default specifier', () => {
expect(
transformCjsImport('export { default } from "react"', url, rawUrl, 0),
transformCjsImport(
'export { default } from "react"',
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
'const __vite__cjsExportDefault_0 = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react; ' +
Expand All @@ -105,6 +164,8 @@ describe('transformCjsImport', () => {
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
Expand All @@ -118,6 +179,8 @@ describe('transformCjsImport', () => {
url,
rawUrl,
0,
'',
config,
),
).toBe(
'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' +
Expand Down
42 changes: 39 additions & 3 deletions packages/vite/src/node/plugins/importAnalysis.ts
Expand Up @@ -585,7 +585,14 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
}
} else if (needsInterop) {
debug?.(`${url} needs interop`)
interopNamedImports(str(), importSpecifier, url, index)
interopNamedImports(
str(),
importSpecifier,
url,
index,
importer,
config,
)
rewriteDone = true
}
}
Expand All @@ -596,7 +603,14 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
url.includes(browserExternalId) &&
source.slice(expStart, start).includes('{')
) {
interopNamedImports(str(), importSpecifier, url, index)
interopNamedImports(
str(),
importSpecifier,
url,
index,
importer,
config,
)
rewriteDone = true
}
if (!rewriteDone) {
Expand Down Expand Up @@ -811,6 +825,8 @@ export function interopNamedImports(
importSpecifier: ImportSpecifier,
rewrittenUrl: string,
importIndex: number,
importer: string,
config: ResolvedConfig,
): void {
const source = str.original
const {
Expand All @@ -831,7 +847,14 @@ export function interopNamedImports(
} else {
const exp = source.slice(expStart, expEnd)
const rawUrl = source.slice(start, end)
const rewritten = transformCjsImport(exp, rewrittenUrl, rawUrl, importIndex)
const rewritten = transformCjsImport(
exp,
rewrittenUrl,
rawUrl,
importIndex,
importer,
config,
)
if (rewritten) {
str.overwrite(expStart, expEnd, rewritten, { contentOnly: true })
} else {
Expand Down Expand Up @@ -861,6 +884,8 @@ export function transformCjsImport(
url: string,
rawUrl: string,
importIndex: number,
importer: string,
config: ResolvedConfig,
): string | undefined {
const node = (
parseJS(importExp, {
Expand All @@ -869,7 +894,18 @@ export function transformCjsImport(
}) as any
).body[0] as Node

// `export * from '...'` may cause unexpected problem, so give it a warning
if (
config.command === 'serve' &&
node.type === 'ExportAllDeclaration' &&
!node.exported
) {
config.logger.warn(
colors.yellow(
`\nUnable to interop \`${importExp}\` in ${importer}, this may lose module exports. Please export "${rawUrl}" as ESM or use named exports instead, e.g. \`export { A, B } from "${rawUrl}"\``,
),
)
} else if (
node.type === 'ImportDeclaration' ||
node.type === 'ExportNamedDeclaration'
) {
Expand Down
9 changes: 8 additions & 1 deletion packages/vite/src/node/plugins/importAnalysisBuild.ts
Expand Up @@ -338,7 +338,14 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
}
} else if (needsInterop) {
// config.logger.info(`${url} needs interop`)
interopNamedImports(str(), imports[index], url, index)
interopNamedImports(
str(),
imports[index],
url,
index,
importer,
config,
)
rewriteDone = true
}
if (!rewriteDone) {
Expand Down

0 comments on commit 5136b9b

Please sign in to comment.