mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-29 09:02:03 +00:00
feat: improved externals and experimental trace with vercel/nft
This commit is contained in:
parent
a05c806f85
commit
5bbdc2bc65
@ -5,6 +5,7 @@ import Hookable, { configHooksT } from 'hookable'
|
||||
import type { Preset } from '@nuxt/un'
|
||||
import { tryImport, resolvePath, detectTarget, extendPreset } from './utils'
|
||||
import * as PRESETS from './presets'
|
||||
import type { NodeExternalsOptions } from './rollup/plugins/externals'
|
||||
|
||||
export interface ServerMiddleware {
|
||||
route: string
|
||||
@ -18,7 +19,7 @@ export interface SigmaContext {
|
||||
inlineChunks: boolean
|
||||
minify: boolean
|
||||
sourceMap: boolean
|
||||
externals: boolean
|
||||
externals: boolean | NodeExternalsOptions
|
||||
analyze: boolean
|
||||
entry: string
|
||||
node: boolean
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { dirname, join, relative, resolve } from 'upath'
|
||||
import { InputOptions, OutputOptions } from 'rollup'
|
||||
import defu from 'defu'
|
||||
import { terser } from 'rollup-plugin-terser'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import nodeResolve from '@rollup/plugin-node-resolve'
|
||||
@ -51,6 +52,8 @@ export const getRollupConfig = (sigmaContext: SigmaContext) => {
|
||||
|
||||
const env = un.env(nodePreset, builtinPreset, sigmaContext.env)
|
||||
|
||||
delete env.alias['node-fetch'] // FIX ME
|
||||
|
||||
if (sigmaContext.sourceMap) {
|
||||
env.polyfill.push('source-map-support/register')
|
||||
}
|
||||
@ -165,15 +168,27 @@ export const getRollupConfig = (sigmaContext: SigmaContext) => {
|
||||
}
|
||||
}))
|
||||
|
||||
// External Plugin
|
||||
if (sigmaContext.externals) {
|
||||
rollupConfig.plugins.push(externals({
|
||||
relativeTo: sigmaContext.output.serverDir,
|
||||
include: [
|
||||
sigmaContext._internal.runtimeDir,
|
||||
...sigmaContext.middleware.map(m => m.handle)
|
||||
const moduleDirectories = [
|
||||
resolve(sigmaContext._nuxt.rootDir, 'node_modules'),
|
||||
resolve(MODULE_DIR, 'node_modules'),
|
||||
resolve(MODULE_DIR, '../node_modules'),
|
||||
'node_modules'
|
||||
]
|
||||
}))
|
||||
|
||||
// Externals Plugin
|
||||
if (sigmaContext.externals) {
|
||||
rollupConfig.plugins.push(externals(defu(sigmaContext.externals as any, {
|
||||
outDir: sigmaContext.output.serverDir,
|
||||
moduleDirectories,
|
||||
ignore: [
|
||||
sigmaContext._internal.runtimeDir,
|
||||
...(sigmaContext._nuxt.dev ? [] : [sigmaContext._nuxt.buildDir]),
|
||||
...sigmaContext.middleware.map(m => m.handle)
|
||||
],
|
||||
traceOptions: {
|
||||
base: sigmaContext._nuxt.rootDir
|
||||
}
|
||||
})))
|
||||
}
|
||||
|
||||
// https://github.com/rollup/plugins/tree/master/packages/node-resolve
|
||||
@ -181,11 +196,7 @@ export const getRollupConfig = (sigmaContext: SigmaContext) => {
|
||||
extensions,
|
||||
preferBuiltins: true,
|
||||
rootDir: sigmaContext._nuxt.rootDir,
|
||||
moduleDirectories: [
|
||||
resolve(sigmaContext._nuxt.rootDir, 'node_modules'),
|
||||
resolve(MODULE_DIR, 'node_modules'),
|
||||
'node_modules'
|
||||
],
|
||||
moduleDirectories,
|
||||
mainFields: ['main'] // Force resolve CJS (@vue/runtime-core ssrUtils)
|
||||
}))
|
||||
|
||||
|
@ -1,24 +1,62 @@
|
||||
import { isAbsolute, relative } from 'upath'
|
||||
import { isAbsolute, relative } from 'path'
|
||||
import type { Plugin } from 'rollup'
|
||||
import { resolve, dirname } from 'upath'
|
||||
import { copyFile, mkdirp } from 'fs-extra'
|
||||
import { nodeFileTrace, NodeFileTraceOptions } from '@vercel/nft'
|
||||
|
||||
export function externals ({ include = [], relativeTo }) {
|
||||
return {
|
||||
name: 'externals',
|
||||
resolveId (source) {
|
||||
if (
|
||||
source[0] === '.' || // Compile relative imports
|
||||
source[0] === '\x00' || // Skip helpers
|
||||
source.includes('?') || // Skip helpers
|
||||
include.find(i => source.startsWith(i))
|
||||
) { return null }
|
||||
|
||||
if (!isAbsolute(source)) {
|
||||
source = require.resolve(source)
|
||||
export interface NodeExternalsOptions {
|
||||
ignore?: string[]
|
||||
outDir?: string
|
||||
trace?: boolean
|
||||
traceOptions?: NodeFileTraceOptions
|
||||
moduleDirectories?: string[]
|
||||
}
|
||||
|
||||
export function externals (opts: NodeExternalsOptions): Plugin {
|
||||
const resolvedExternals = {}
|
||||
return {
|
||||
id: relative(relativeTo, source),
|
||||
name: 'node-externals',
|
||||
resolveId (id) {
|
||||
// Internals
|
||||
if (id.startsWith('\x00') || id.includes('?')) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Resolve relative paths and exceptions
|
||||
if (id.startsWith('.') || opts.ignore.find(i => id.startsWith(i))) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (const dir of opts.moduleDirectories) {
|
||||
if (id.startsWith(dir)) {
|
||||
id = id.substr(dir.length + 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
resolvedExternals[id] = require.resolve(id, { paths: opts.moduleDirectories })
|
||||
} catch (_err) { }
|
||||
|
||||
return {
|
||||
id: isAbsolute(id) ? relative(opts.outDir, id) : id,
|
||||
external: true
|
||||
}
|
||||
},
|
||||
async buildEnd () {
|
||||
if (opts.trace) {
|
||||
const { fileList } = await nodeFileTrace(Object.values(resolvedExternals), opts.traceOptions)
|
||||
await Promise.all(fileList.map(async (file) => {
|
||||
if (!file.startsWith('node_modules')) {
|
||||
return
|
||||
}
|
||||
// TODO: Minify package.json
|
||||
const src = resolve(opts.traceOptions.base, file)
|
||||
const dst = resolve(opts.outDir, file)
|
||||
await mkdirp(dirname(dst))
|
||||
await copyFile(src, dst)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { readFile } from 'fs-extra'
|
||||
import chalk from 'chalk'
|
||||
|
||||
export async function printFSTree (dir) {
|
||||
const files = await globby('**/*.js', { cwd: dir })
|
||||
const files = await globby('**/*.*', { cwd: dir })
|
||||
|
||||
const items = (await Promise.all(files.map(async (file) => {
|
||||
const path = resolve(dir, file)
|
||||
@ -19,16 +19,27 @@ export async function printFSTree (dir) {
|
||||
let totalSize = 0
|
||||
let totalGzip = 0
|
||||
|
||||
let totalNodeModulesSize = 0
|
||||
let totalNodeModulesGzip = 0
|
||||
|
||||
items.forEach((item, index) => {
|
||||
let dir = dirname(item.file)
|
||||
if (dir === '.') { dir = '' }
|
||||
const rpath = relative(process.cwd(), item.path)
|
||||
const treeChar = index === items.length - 1 ? '└─' : '├─'
|
||||
process.stdout.write(chalk.gray(` ${treeChar} ${rpath} (${prettyBytes(item.size)}) (${prettyBytes(item.gzip)} gzip)\n`))
|
||||
|
||||
const isNodeModules = item.file.includes('node_modules')
|
||||
|
||||
if (isNodeModules) {
|
||||
totalNodeModulesSize += item.size
|
||||
totalNodeModulesGzip += item.gzip
|
||||
return
|
||||
}
|
||||
|
||||
process.stdout.write(chalk.gray(` ${treeChar} ${rpath} (${prettyBytes(item.size)}) (${prettyBytes(item.gzip)} gzip)\n`))
|
||||
totalSize += item.size
|
||||
totalGzip += item.gzip
|
||||
})
|
||||
|
||||
process.stdout.write(`${chalk.cyan('Σ Total size:')} ${prettyBytes(totalSize)} (${prettyBytes(totalGzip)} gzip)\n`)
|
||||
process.stdout.write(`${chalk.cyan('Σ Total size:')} ${prettyBytes(totalSize + totalNodeModulesSize)} (${prettyBytes(totalGzip + totalNodeModulesGzip)} gzip)\n`)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user