From 29171bd1053e24132b3ab23ac50535edde6b2323 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 7 Feb 2022 13:45:47 +0000 Subject: [PATCH] fix: sanitize import filenames in generated imports (#2216) --- packages/bridge/package.json | 1 + packages/bridge/src/vite/templates.ts | 13 ++++----- packages/kit/package.json | 1 + packages/kit/src/components.ts | 5 ++-- packages/kit/src/internal/template.ts | 7 +++-- packages/nitro/package.json | 1 + packages/nitro/src/build.ts | 3 +- packages/nitro/src/presets/browser.ts | 7 +++-- packages/nitro/src/rollup/config.ts | 3 +- packages/nitro/src/rollup/plugins/assets.ts | 10 +++++-- .../src/rollup/plugins/dynamic-require.ts | 13 ++++----- .../nitro/src/rollup/plugins/middleware.ts | 16 ++++++---- packages/nitro/src/rollup/plugins/storage.ts | 5 ++-- packages/nuxt3/package.json | 1 + packages/nuxt3/src/auto-imports/module.ts | 3 +- packages/nuxt3/src/auto-imports/utils.ts | 7 +++-- packages/nuxt3/src/components/loader.ts | 3 +- packages/nuxt3/src/components/templates.ts | 13 ++++----- packages/nuxt3/src/core/templates.ts | 27 +++++++---------- packages/nuxt3/src/pages/module.ts | 29 ++++++++++--------- packages/nuxt3/src/pages/utils.ts | 15 +++++----- packages/nuxt3/test/auto-imports.test.ts | 6 ++-- packages/vite/package.json | 1 + packages/vite/src/dev-bundler.ts | 10 ++++--- yarn.lock | 12 ++++++++ 25 files changed, 118 insertions(+), 94 deletions(-) diff --git a/packages/bridge/package.json b/packages/bridge/package.json index dc4e0aff6d7..02298361041 100644 --- a/packages/bridge/package.json +++ b/packages/bridge/package.json @@ -38,6 +38,7 @@ "globby": "^13.1.1", "h3": "^0.3.9", "hash-sum": "^2.0.0", + "knitwork": "^0.1.0", "magic-string": "^0.25.7", "mlly": "^0.4.1", "murmurhash-es": "^0.1.1", diff --git a/packages/bridge/src/vite/templates.ts b/packages/bridge/src/vite/templates.ts index 845980bc7ea..ac5971bdce0 100644 --- a/packages/bridge/src/vite/templates.ts +++ b/packages/bridge/src/vite/templates.ts @@ -2,6 +2,7 @@ import hash from 'hash-sum' import { resolve } from 'pathe' import type { Nuxt, NuxtApp } from '@nuxt/schema' +import { genImport, genObjectFromRawEntries } from 'knitwork' type TemplateContext = { nuxt: Nuxt; @@ -24,10 +25,8 @@ export const middlewareTemplate = { id: m.name || m.src.replace(/[\\/]/g, '/').replace(/\.(js|ts)$/, '') } }) - return `${_middleware.map(m => `import $${hash(m.id)} from '${m.filePath}'`).join('\n')} -const middleware = { -${_middleware.map(m => ` ['${m.id}']: $${hash(m.id)}`).join(',\n')} -} + return `${_middleware.map(m => genImport(m.filePath, `$${hash(m.id)}`)).join('\n')} +const middleware = ${genObjectFromRawEntries(_middleware.map(m => [m.id, `$${hash(m.id)}`]))} export default middleware` } } @@ -49,14 +48,12 @@ export const storeTemplate = { return `import Vue from 'vue' import Vuex from 'vuex' -${_storeModules.map(s => `import * as $${hash(s.id)} from '${s.filePath}'`).join('\n')} +${_storeModules.map(s => genImport(s.filePath, { name: '*', as: `$${hash(s.id)}` })).join('\n')} Vue.use(Vuex) const VUEX_PROPERTIES = ['state', 'getters', 'actions', 'mutations'] -const storeModules = { -${_storeModules.map(m => ` ['${m.id}']: $${hash(m.id)}`).join(',\n')} -} +const storeModules = ${genObjectFromRawEntries(_storeModules.map(m => [m.id, `$${hash(m.id)}`]))} export function createStore() { let store = normalizeRoot(storeModules.root || {}) diff --git a/packages/kit/package.json b/packages/kit/package.json index c58c5ce6ca4..b4e81e9e541 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -20,6 +20,7 @@ "globby": "^13.1.1", "hash-sum": "^2.0.0", "jiti": "^1.12.15", + "knitwork": "^0.1.0", "lodash.template": "^4.5.0", "mlly": "^0.4.1", "pathe": "^0.2.0", diff --git a/packages/kit/src/components.ts b/packages/kit/src/components.ts index 6b8486ca231..44092da047b 100644 --- a/packages/kit/src/components.ts +++ b/packages/kit/src/components.ts @@ -1,5 +1,6 @@ import { pascalCase, kebabCase } from 'scule' import type { ComponentsDir, Component } from '@nuxt/schema' +import { genDynamicImport } from 'knitwork' import { useNuxt } from './context' import { assertNuxtCompatibility } from './compatibility' @@ -43,8 +44,8 @@ export async function addComponent (opts: AddComponentOptions) { shortPath: opts.filePath, async: false, level: 0, - asyncImport: `() => import('${opts.filePath}').then(r => r['${opts.export || 'default'}'])`, - import: `require('${opts.filePath}')['${opts.export || 'default'}']`, + asyncImport: `${genDynamicImport(opts.filePath)}.then(r => r['${opts.export || 'default'}'])`, + import: `require(${JSON.stringify(opts.filePath)})['${opts.export || 'default'}']`, ...opts } diff --git a/packages/kit/src/internal/template.ts b/packages/kit/src/internal/template.ts index 46d63d02862..863aa87f630 100644 --- a/packages/kit/src/internal/template.ts +++ b/packages/kit/src/internal/template.ts @@ -3,6 +3,7 @@ import lodashTemplate from 'lodash.template' import hash from 'hash-sum' import { camelCase } from 'scule' import { basename, extname } from 'pathe' +import { genDynamicImport, genImport } from 'knitwork' import type { NuxtTemplate } from '@nuxt/schema' @@ -23,7 +24,7 @@ export async function compileTemplate (template: NuxtTemplate, ctx: any) { throw new Error('Invalid template: ' + JSON.stringify(template)) } -const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"{(.+)}"/g, '$1') +const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"{(.+)}"(?=,?$)/gm, r => JSON.parse(r).replace(/^{(.*)}$/, '$1')) const importName = (src: string) => `${camelCase(basename(src, extname(src))).replace(/[^a-zA-Z?\d\s:]/g, '')}_${hash(src)}` @@ -33,9 +34,9 @@ const importSources = (sources: string | string[], { lazy = false } = {}) => { } return sources.map((src) => { if (lazy) { - return `const ${importName(src)} = () => import('${src}' /* webpackChunkName: '${src}' */)` + return `const ${importName(src)} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}` } - return `import ${importName(src)} from '${src}'` + return genImport(src, importName(src)) }).join('\n') } diff --git a/packages/nitro/package.json b/packages/nitro/package.json index d7f98ed9ce9..6275ad6a056 100644 --- a/packages/nitro/package.json +++ b/packages/nitro/package.json @@ -48,6 +48,7 @@ "http-proxy": "^1.18.1", "is-primitive": "^3.0.1", "jiti": "^1.12.15", + "knitwork": "^0.1.0", "listhen": "^0.2.6", "mime": "^3.0.0", "mlly": "^0.4.1", diff --git a/packages/nitro/src/build.ts b/packages/nitro/src/build.ts index bdf2ddbd7c8..9d9666565a2 100644 --- a/packages/nitro/src/build.ts +++ b/packages/nitro/src/build.ts @@ -2,6 +2,7 @@ import { relative, resolve, join } from 'pathe' import consola from 'consola' import * as rollup from 'rollup' import fse from 'fs-extra' +import { genDynamicImport } from 'knitwork' import { printFSTree } from './utils/tree' import { getRollupConfig } from './rollup/config' import { hl, prettyPath, serializeTemplate, writeFile, isDirectory, replaceAll } from './utils' @@ -73,7 +74,7 @@ export async function writeTypes (nitroContext: NitroContext) { if (typeof mw.handle !== 'string') { continue } const relativePath = relative(nitroContext._nuxt.buildDir, mw.handle).replace(/\.[a-z]+$/, '') routeTypes[mw.route] = routeTypes[mw.route] || [] - routeTypes[mw.route].push(`Awaited>`) + routeTypes[mw.route].push(`Awaited>`) } const lines = [ diff --git a/packages/nitro/src/presets/browser.ts b/packages/nitro/src/presets/browser.ts index 5cc7a5d840f..5d9c8bf527c 100644 --- a/packages/nitro/src/presets/browser.ts +++ b/packages/nitro/src/presets/browser.ts @@ -2,6 +2,7 @@ import { existsSync, promises as fsp } from 'fs' import { resolve } from 'pathe' import consola from 'consola' import { joinURL } from 'ufo' +import { genString } from 'knitwork' import { extendPreset, prettyPath } from '../utils' import { NitroPreset, NitroContext, NitroInput } from '../context' import { worker } from './worker' @@ -13,7 +14,7 @@ export const browser: NitroPreset = extendPreset(worker, (input: NitroInput) => const script = `` @@ -27,7 +28,7 @@ if ('serviceWorker' in navigator) {