fix(nuxt): reduce usage of cjs utilities (#27642)

This commit is contained in:
Daniel Roe 2024-06-16 00:03:24 +01:00 committed by GitHub
parent 44cada95a6
commit 2de885bab5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 37 additions and 20 deletions

View File

@ -43,8 +43,11 @@ export function normalizePlugin (plugin: NuxtPlugin | string): NuxtPlugin {
* Note: By default plugin is prepended to the plugins array. You can use second argument to append (push) instead. * Note: By default plugin is prepended to the plugins array. You can use second argument to append (push) instead.
* @example * @example
* ```js * ```js
* import { createResolver } from '@nuxt/kit'
* const resolver = createResolver(import.meta.url)
*
* addPlugin({ * addPlugin({
* src: path.resolve(__dirname, 'templates/foo.js'), * src: resolver.resolve('templates/foo.js'),
* filename: 'foo.server.js' // [optional] only include in server bundle * filename: 'foo.server.js' // [optional] only include in server bundle
* }) * })
* ``` * ```

View File

@ -355,6 +355,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
nitroConfig.rollupConfig!.plugins!.push( nitroConfig.rollupConfig!.plugins!.push(
ImportProtectionPlugin.rollup({ ImportProtectionPlugin.rollup({
rootDir: nuxt.options.rootDir, rootDir: nuxt.options.rootDir,
modulesDir: nuxt.options.modulesDir,
patterns: nuxtImportProtections(nuxt, { isNitro: true }), patterns: nuxtImportProtections(nuxt, { isNitro: true }),
exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/], exclude: [/core[\\/]runtime[\\/]nitro[\\/]renderer/],
}), }),

View File

@ -167,6 +167,7 @@ async function initNuxt (nuxt: Nuxt) {
// Exclude top-level resolutions by plugins // Exclude top-level resolutions by plugins
exclude: [join(nuxt.options.srcDir, 'index.html')], exclude: [join(nuxt.options.srcDir, 'index.html')],
patterns: nuxtImportProtections(nuxt), patterns: nuxtImportProtections(nuxt),
modulesDir: nuxt.options.modulesDir,
} }
addVitePlugin(() => ImportProtectionPlugin.vite(config)) addVitePlugin(() => ImportProtectionPlugin.vite(config))
addWebpackPlugin(() => ImportProtectionPlugin.webpack(config)) addWebpackPlugin(() => ImportProtectionPlugin.webpack(config))

View File

@ -1,14 +1,13 @@
import { createRequire } from 'node:module'
import { createUnplugin } from 'unplugin' import { createUnplugin } from 'unplugin'
import { logger } from '@nuxt/kit' import { logger } from '@nuxt/kit'
import { resolvePath } from 'mlly'
import { isAbsolute, join, relative, resolve } from 'pathe' import { isAbsolute, join, relative, resolve } from 'pathe'
import escapeRE from 'escape-string-regexp' import escapeRE from 'escape-string-regexp'
import type { NuxtOptions } from 'nuxt/schema' import type { NuxtOptions } from 'nuxt/schema'
const _require = createRequire(import.meta.url)
interface ImportProtectionOptions { interface ImportProtectionOptions {
rootDir: string rootDir: string
modulesDir: string[]
patterns: [importPattern: string | RegExp, warning?: string][] patterns: [importPattern: string | RegExp, warning?: string][]
exclude?: Array<RegExp | string> exclude?: Array<RegExp | string>
} }
@ -58,6 +57,7 @@ export const nuxtImportProtections = (nuxt: { options: NuxtOptions }, options: {
export const ImportProtectionPlugin = createUnplugin(function (options: ImportProtectionOptions) { export const ImportProtectionPlugin = createUnplugin(function (options: ImportProtectionOptions) {
const cache: Record<string, Map<string | RegExp, boolean>> = {} const cache: Record<string, Map<string | RegExp, boolean>> = {}
const importersToExclude = options?.exclude || [] const importersToExclude = options?.exclude || []
const proxy = resolvePath('unenv/runtime/mock/proxy', { url: options.modulesDir })
return { return {
name: 'nuxt:import-protection', name: 'nuxt:import-protection',
enforce: 'pre', enforce: 'pre',
@ -85,7 +85,7 @@ export const ImportProtectionPlugin = createUnplugin(function (options: ImportPr
matched = true matched = true
} }
if (matched) { if (matched) {
return _require.resolve('unenv/runtime/mock/proxy') return proxy
} }
return null return null
}, },

View File

@ -1,7 +1,7 @@
import { readFileSync } from 'node:fs' import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { join } from 'pathe' import { findExports } from 'mlly'
import { createCommonJS, findExports } from 'mlly'
import * as VueFunctions from 'vue' import * as VueFunctions from 'vue'
import type { Import } from 'unimport' import type { Import } from 'unimport'
import { createUnimport } from 'unimport' import { createUnimport } from 'unimport'
@ -59,8 +59,8 @@ const excludedNuxtHelpers = ['useHydration', 'useHead', 'useSeoMeta', 'useServer
describe('imports:nuxt', () => { describe('imports:nuxt', () => {
try { try {
const { __dirname } = createCommonJS(import.meta.url) const entrypointPath = fileURLToPath(new URL('../src/app/composables/index.ts', import.meta.url))
const entrypointContents = readFileSync(join(__dirname, '../src/app/composables/index.ts'), 'utf8') const entrypointContents = readFileSync(entrypointPath, 'utf8')
const names = findExports(entrypointContents).flatMap(i => i.names || i.name) const names = findExports(entrypointContents).flatMap(i => i.names || i.name)
for (let name of names) { for (let name of names) {

View File

@ -1,3 +1,4 @@
import { fileURLToPath } from 'node:url'
import { normalize } from 'pathe' import { normalize } from 'pathe'
import { describe, expect, it } from 'vitest' import { describe, expect, it } from 'vitest'
import { ImportProtectionPlugin, nuxtImportProtections } from '../src/core/plugins/import-protection' import { ImportProtectionPlugin, nuxtImportProtections } from '../src/core/plugins/import-protection'
@ -40,6 +41,7 @@ describe('import protection', () => {
const transformWithImportProtection = (id: string, importer: string) => { const transformWithImportProtection = (id: string, importer: string) => {
const plugin = ImportProtectionPlugin.rollup({ const plugin = ImportProtectionPlugin.rollup({
rootDir: '/root', rootDir: '/root',
modulesDir: [fileURLToPath(new URL('..', import.meta.url))],
patterns: nuxtImportProtections({ patterns: nuxtImportProtections({
options: { options: {
modules: ['some-nuxt-module'], modules: ['some-nuxt-module'],

View File

@ -1,10 +1,11 @@
import { fileURLToPath } from 'node:url'
import { resolve } from 'pathe' import { resolve } from 'pathe'
import { expect, it, vi } from 'vitest' import { expect, it, vi } from 'vitest'
import type { ComponentsDir } from 'nuxt/schema' import type { ComponentsDir } from 'nuxt/schema'
import { scanComponents } from '../src/components/scan' import { scanComponents } from '../src/components/scan'
const fixtureDir = resolve(__dirname, 'fixture') const fixtureDir = fileURLToPath(new URL('fixture', import.meta.url))
const rFixture = (...p: string[]) => resolve(fixtureDir, ...p) const rFixture = (...p: string[]) => resolve(fixtureDir, ...p)
vi.mock('@nuxt/kit', () => ({ vi.mock('@nuxt/kit', () => ({

View File

@ -1,6 +1,6 @@
import { resolve } from 'pathe' import { fileURLToPath } from 'node:url'
export const fixtureDir = resolve(__dirname, 'fixture') export const fixtureDir = fileURLToPath(new URL('fixture', import.meta.url))
export function normalizeLineEndings (str: string, normalized = '\n') { export function normalizeLineEndings (str: string, normalized = '\n') {
return str.replace(/\r?\n/g, normalized) return str.replace(/\r?\n/g, normalized)

View File

@ -1,10 +1,13 @@
import { join, resolve } from 'node:path' import { join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { promises as fsp } from 'node:fs' import { promises as fsp } from 'node:fs'
import type { Plugin } from 'vite' import type { Plugin } from 'vite'
import { template } from 'lodash-es' import { template } from 'lodash-es'
import genericMessages from '../templates/messages.json' import genericMessages from '../templates/messages.json'
const r = (...path: string[]) => resolve(join(__dirname, '..', ...path)) const templatesRoot = fileURLToPath(new URL('..', import.meta.url))
const r = (...path: string[]) => resolve(join(templatesRoot, ...path))
export const DevRenderingPlugin = () => { export const DevRenderingPlugin = () => {
return <Plugin>{ return <Plugin>{

View File

@ -1,8 +1,11 @@
import { join, resolve } from 'node:path' import { join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { promises as fsp } from 'node:fs' import { promises as fsp } from 'node:fs'
import { globby } from 'globby' import { globby } from 'globby'
const r = (...path: string[]) => resolve(join(__dirname, '..', ...path)) const templatesRoot = fileURLToPath(new URL('..', import.meta.url))
const r = (...path: string[]) => resolve(join(templatesRoot, ...path))
async function main () { async function main () {
const templates = await globby(r('dist/templates/*.js')) const templates = await globby(r('dist/templates/*.js'))

View File

@ -1,5 +1,5 @@
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { join } from 'node:path' import { resolve } from 'node:path'
import { readdirSync } from 'node:fs' import { readdirSync } from 'node:fs'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
@ -8,7 +8,8 @@ import UnoCSS from 'unocss/vite'
import { DevRenderingPlugin } from './lib/dev' import { DevRenderingPlugin } from './lib/dev'
import { RenderPlugin } from './lib/render' import { RenderPlugin } from './lib/render'
const r = (...path: string[]) => fileURLToPath(new URL(join(...path), import.meta.url)) const rootDir = fileURLToPath(new URL('.', import.meta.url))
const r = (...path: string[]) => resolve(rootDir, ...path)
export default defineConfig({ export default defineConfig({
build: { build: {
@ -32,7 +33,7 @@ export default defineConfig({
], ],
server: { server: {
fs: { fs: {
allow: ['./templates', __dirname], allow: ['./templates', rootDir],
}, },
}, },
}) })

View File

@ -19,6 +19,7 @@ export function resolveCSSOptions (nuxt: Nuxt): ViteConfig['css'] {
for (const [name, opts] of plugins) { for (const [name, opts] of plugins) {
if (opts) { if (opts) {
// TODO: remove use of requireModule in favour of ESM import
const plugin = requireModule(name, { const plugin = requireModule(name, {
paths: [ paths: [
...nuxt.options.modulesDir, ...nuxt.options.modulesDir,

View File

@ -1,5 +1,5 @@
import { fileURLToPath } from 'node:url'
import createResolver from 'postcss-import-resolver' import createResolver from 'postcss-import-resolver'
import { createCommonJS } from 'mlly'
import { requireModule } from '@nuxt/kit' import { requireModule } from '@nuxt/kit'
import type { Nuxt } from '@nuxt/schema' import type { Nuxt } from '@nuxt/schema'
import { defu } from 'defu' import { defu } from 'defu'
@ -61,9 +61,10 @@ export const getPostcssConfig = (nuxt: Nuxt) => {
// Keep the order of default plugins // Keep the order of default plugins
if (!Array.isArray(postcssOptions.plugins) && isPureObject(postcssOptions.plugins)) { if (!Array.isArray(postcssOptions.plugins) && isPureObject(postcssOptions.plugins)) {
// Map postcss plugins into instances on object mode once // Map postcss plugins into instances on object mode once
const cjs = createCommonJS(import.meta.url) const cwd = fileURLToPath(new URL('.', import.meta.url))
postcssOptions.plugins = sortPlugins(postcssOptions).map((pluginName: string) => { postcssOptions.plugins = sortPlugins(postcssOptions).map((pluginName: string) => {
const pluginFn = requireModule(pluginName, { paths: [cjs.__dirname] }) // TODO: remove use of requireModule in favour of ESM import
const pluginFn = requireModule(pluginName, { paths: [cwd] })
const pluginOptions = postcssOptions.plugins[pluginName] const pluginOptions = postcssOptions.plugins[pluginName]
if (!pluginOptions || typeof pluginFn !== 'function') { return null } if (!pluginOptions || typeof pluginFn !== 'function') { return null }
return pluginFn(pluginOptions) return pluginFn(pluginOptions)