Skip to content

Commit

Permalink
Merge branch 'main' into remove-node-12-support
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinigami92 committed Apr 23, 2022
2 parents f63e3a0 + fc89057 commit b84ccd5
Show file tree
Hide file tree
Showing 23 changed files with 229 additions and 118 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/ci.yml
Expand Up @@ -27,12 +27,17 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
node_version: [14, 16, 17]
node_version: [14, 16, 18]
include:
- os: macos-latest
node_version: 16
- os: macos-latest
node_version: 18
- os: windows-latest
node_version: 16
# Maybe bug with jest on windows and node-v18
# - os: windows-latest
# node_version: 18
fail-fast: false

name: "Build&Test: node-${{ matrix.node_version }}, ${{ matrix.os }}"
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -95,6 +95,8 @@ test('should work', async () => {

Some common test helpers, e.g. `testDir`, `isBuild` or `editFile` are available in `packages/playground/testUtils.ts`.

Note: The test build environment uses a [different default set of Vite config](https://github.com/vitejs/vite/blob/9c6501d9c363eaa3c1e7708d531fb2a92b633db6/scripts/jestPerTestSetup.ts#L102-L122) to skip transpilation during tests to make it faster. This may produce a different result compared to the default production build.

### Extending the Test Suite

To add new tests, you should find a related playground to the fix or feature (or create a new one). As an example, static assets loading are tested in the [assets playground](https://github.com/vitejs/vite/tree/main/packages/playground/assets). In this Vite App, there is a test for `?raw` imports, with [a section is defined in the `index.html` for it](https://github.com/vitejs/vite/blob/71215533ac60e8ff566dc3467feabfc2c71a01e2/packages/playground/assets/index.html#L121):
Expand Down
30 changes: 18 additions & 12 deletions docs/guide/api-hmr.md
Expand Up @@ -10,21 +10,27 @@ Vite exposes its manual HMR API via the special `import.meta.hot` object:

```ts
interface ImportMeta {
readonly hot?: {
readonly data: any
readonly hot?: ViteHotContext
}

interface ViteHotContext {
readonly data: any

accept(): void
accept(cb: (mod: any) => void): void
accept(dep: string, cb: (mod: any) => void): void
accept(deps: string[], cb: (mods: any[]) => void): void
accept(): void
accept(cb: (mod: any) => void): void
accept(dep: string, cb: (mod: any) => void): void
accept(deps: readonly string[], cb: (mods: any[]) => void): void

prune(cb: () => void): void
dispose(cb: (data: any) => void): void
decline(): void
invalidate(): void
dispose(cb: (data: any) => void): void
decline(): void
invalidate(): void

on(event: string, cb: (...args: any[]) => void): void
}
// `InferCustomEventPayload` provides types for built-in Vite events
on<T extends string>(
event: T,
cb: (payload: InferCustomEventPayload<T>) => void
): void
send<T extends string>(event: T, data?: InferCustomEventPayload<T>): void
}
```

Expand Down
6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -37,7 +37,7 @@
"@microsoft/api-extractor": "^7.22.2",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.4.1",
"@types/node": "^16.11.27",
"@types/node": "^17.0.25",
"@types/prompts": "^2.0.14",
"@types/semver": "^7.3.9",
"@typescript-eslint/eslint-plugin": "^5.20.0",
Expand All @@ -46,12 +46,12 @@
"cross-env": "^7.0.3",
"esbuild": "^0.14.27",
"eslint": "^8.13.0",
"eslint-define-config": "^1.3.0",
"eslint-define-config": "^1.4.0",
"eslint-plugin-node": "^11.1.0",
"execa": "^5.1.1",
"fs-extra": "^10.1.0",
"jest": "^27.5.1",
"lint-staged": "^12.3.8",
"lint-staged": "^12.4.0",
"minimist": "^1.2.6",
"node-fetch": "^2.6.6",
"npm-run-all": "^4.1.5",
Expand Down
11 changes: 10 additions & 1 deletion packages/playground/ssr-webworker/vite.config.js
Expand Up @@ -10,9 +10,18 @@ module.exports = {
},
ssr: {
target: 'webworker',
noExternal: true
noExternal: ['this-should-be-replaced-by-the-boolean']
},
plugins: [
{
config() {
return {
ssr: {
noExternal: true
}
}
}
},
{
config() {
return {
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/worker/__tests__/es/es-worker.spec.ts
Expand Up @@ -60,7 +60,7 @@ if (isBuild) {
// assert correct files
test('inlined code generation', async () => {
const files = fs.readdirSync(assetsDir)
expect(files.length).toBe(22)
expect(files.length).toBe(21)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const worker = files.find((f) => f.includes('my-worker'))
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/worker/__tests__/iife/worker.spec.ts
Expand Up @@ -63,7 +63,7 @@ if (isBuild) {
// assert correct files
test('inlined code generation', async () => {
const files = fs.readdirSync(assetsDir)
expect(files.length).toBe(13)
expect(files.length).toBe(12)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const worker = files.find((f) => f.includes('my-worker'))
Expand Down
Expand Up @@ -9,7 +9,7 @@ if (isBuild) {
test('sourcemap generation for web workers', async () => {
const files = fs.readdirSync(assetsDir)
// should have 2 worker chunk
expect(files.length).toBe(25)
expect(files.length).toBe(24)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const indexSourcemap = getSourceMapUrl(content)
Expand Down
Expand Up @@ -9,7 +9,7 @@ if (isBuild) {
test('sourcemap generation for web workers', async () => {
const files = fs.readdirSync(assetsDir)
// should have 2 worker chunk
expect(files.length).toBe(13)
expect(files.length).toBe(12)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const indexSourcemap = getSourceMapUrl(content)
Expand Down
Expand Up @@ -9,7 +9,7 @@ if (isBuild) {
test('sourcemap generation for web workers', async () => {
const files = fs.readdirSync(assetsDir)
// should have 2 worker chunk
expect(files.length).toBe(25)
expect(files.length).toBe(24)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const indexSourcemap = getSourceMapUrl(content)
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-legacy/package.json
Expand Up @@ -23,7 +23,7 @@
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-legacy#readme",
"dependencies": {
"@babel/standalone": "^7.17.9",
"core-js": "^3.22.0",
"core-js": "^3.22.2",
"magic-string": "^0.26.1",
"regenerator-runtime": "^0.13.9",
"systemjs": "^6.12.1"
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/package.json
Expand Up @@ -55,7 +55,7 @@
"@ampproject/remapping": "^2.1.2",
"@babel/parser": "^7.17.9",
"@babel/types": "^7.17.0",
"@jridgewell/trace-mapping": "^0.3.4",
"@jridgewell/trace-mapping": "^0.3.9",
"@rollup/plugin-alias": "^3.1.9",
"@rollup/plugin-commonjs": "^21.1.0",
"@rollup/plugin-dynamic-import-vars": "^1.4.3",
Expand All @@ -71,7 +71,7 @@
"@types/less": "^3.0.3",
"@types/micromatch": "^4.0.2",
"@types/mime": "^2.0.3",
"@types/node": "^16.11.27",
"@types/node": "^17.0.25",
"@types/resolve": "^1.20.1",
"@types/sass": "~1.43.1",
"@types/stylus": "^0.48.37",
Expand Down
19 changes: 19 additions & 0 deletions packages/vite/src/node/__tests__/cleanString.spec.ts
Expand Up @@ -32,6 +32,25 @@ test('strings', () => {
expect(clean).toMatch('const b = "\0\0\0\0"')
})

test('escape character', () => {
const clean = emptyString(`
'1\\'1'
"1\\"1"
"1\\"1\\"1"
"1\\'1'\\"1"
"1'1'"
"1'\\'1\\''\\"1\\"\\""
'1"\\"1\\""\\"1\\"\\"'
'""1""'
'"""1"""'
'""""1""""'
"''1''"
"'''1'''"
"''''1''''"
`)
expect(clean).not.toMatch('1')
})

test('strings comment nested', () => {
expect(
emptyString(`
Expand Down
12 changes: 10 additions & 2 deletions packages/vite/src/node/cleanString.ts
Expand Up @@ -2,7 +2,8 @@ import type { RollupError } from 'rollup'
// bank on the non-overlapping nature of regex matches and combine all filters into one giant regex
// /`([^`\$\{\}]|\$\{(`|\g<1>)*\})*`/g can match nested string template
// but js not support match expression(\g<0>). so clean string template(`...`) in other ways.
const cleanerRE = /"[^"]*"|'[^']*'|\/\*(.|[\r\n])*?\*\/|\/\/.*/g
const cleanerRE =
/"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|\/\*(.|[\r\n])*?\*\/|\/\/.*/g

const blankReplacer = (s: string) => ' '.repeat(s.length)
const stringBlankReplacer = (s: string) =>
Expand All @@ -25,9 +26,16 @@ export function emptyString(raw: string): string {
}

const enum LexerState {
// template string
inTemplateString,
inInterpolationExpression,
inObjectExpression
inObjectExpression,
// strings
inSingleQuoteString,
inDoubleQuoteString,
// comments
inMultilineCommentsRE,
inSinglelineCommentsRE
}

function replaceAt(
Expand Down
3 changes: 2 additions & 1 deletion packages/vite/src/node/config.ts
Expand Up @@ -745,7 +745,8 @@ function mergeConfigRecursively(
} else if (key === 'assetsInclude' && rootPath === '') {
merged[key] = [].concat(existing, value)
continue
} else if (key === 'noExternal' && existing === true) {
} else if (key === 'noExternal' && (existing === true || value === true)) {
merged[key] = true
continue
}

Expand Down
10 changes: 9 additions & 1 deletion packages/vite/src/node/logger.ts
Expand Up @@ -190,7 +190,15 @@ function printServerUrls(
} else {
Object.values(os.networkInterfaces())
.flatMap((nInterface) => nInterface ?? [])
.filter((detail) => detail && detail.address && detail.family === 'IPv4')
.filter(
(detail) =>
detail &&
detail.address &&
// Node < v18
((typeof detail.family === 'string' && detail.family === 'IPv4') ||
// Node >= v18
(typeof detail.family === 'number' && detail.family === 4))
)
.map((detail) => {
const type = detail.address.includes('127.0.0.1')
? 'Local: '
Expand Down
17 changes: 10 additions & 7 deletions packages/vite/src/node/plugins/css.ts
Expand Up @@ -1122,7 +1122,7 @@ export async function hoistAtRules(css: string) {
// to top when multiple files are concatenated.
// match until semicolon that's not in quotes
s.replace(
/@import\s*(?:url\([^\)]*\)|"[^"]*"|'[^']*'|[^;]*).*?;/gm,
/@import\s*(?:url\([^\)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm,
(match) => {
s.appendLeft(0, match)
return ''
Expand All @@ -1131,13 +1131,16 @@ export async function hoistAtRules(css: string) {
// #6333
// CSS @charset must be the top-first in the file, hoist the first to top
let foundCharset = false
s.replace(/@charset\s*(?:"[^"]*"|'[^']*'|[^;]*).*?;/gm, (match) => {
if (!foundCharset) {
s.prepend(match)
foundCharset = true
s.replace(
/@charset\s*(?:"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm,
(match) => {
if (!foundCharset) {
s.prepend(match)
foundCharset = true
}
return ''
}
return ''
})
)
return s.toString()
}

Expand Down
14 changes: 11 additions & 3 deletions packages/vite/src/node/plugins/html.ts
Expand Up @@ -46,7 +46,8 @@ interface ScriptAssetsUrl {
const htmlProxyRE = /\?html-proxy=?[&inline\-css]*&index=(\d+)\.(js|css)$/
const inlineCSSRE = /__VITE_INLINE_CSS__([^_]+_\d+)__/g
// Do not allow preceding '.', but do allow preceding '...' for spread operations
const inlineImportRE = /(?<!(?<!\.\.)\.)\bimport\s*\(("[^"]*"|'[^']*')\)/g
const inlineImportRE =
/(?<!(?<!\.\.)\.)\bimport\s*\(("([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*')\)/g
const htmlLangRE = /\.(html|htm)$/

export const isHTMLProxy = (id: string): boolean => htmlProxyRE.test(id)
Expand Down Expand Up @@ -390,8 +391,15 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
addToHTMLProxyCache(config, filePath, inlineModuleIndex, {
code: styleNode.content
})
js += `\nimport "${id}?html-proxy&index=${inlineModuleIndex}.css"`
shouldRemove = true
js += `\nimport "${id}?html-proxy&inline-css&index=${inlineModuleIndex}.css"`

// will transform in `applyHtmlTransforms`
s.overwrite(
styleNode.loc.start.offset,
styleNode.loc.end.offset,
`__VITE_INLINE_CSS__${cleanUrl(id)}_${inlineModuleIndex}__`,
{ contentOnly: true }
)
}

if (shouldRemove) {
Expand Down

0 comments on commit b84ccd5

Please sign in to comment.