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 type { Preset } from '@nuxt/un'
|
||||||
import { tryImport, resolvePath, detectTarget, extendPreset } from './utils'
|
import { tryImport, resolvePath, detectTarget, extendPreset } from './utils'
|
||||||
import * as PRESETS from './presets'
|
import * as PRESETS from './presets'
|
||||||
|
import type { NodeExternalsOptions } from './rollup/plugins/externals'
|
||||||
|
|
||||||
export interface ServerMiddleware {
|
export interface ServerMiddleware {
|
||||||
route: string
|
route: string
|
||||||
@ -18,7 +19,7 @@ export interface SigmaContext {
|
|||||||
inlineChunks: boolean
|
inlineChunks: boolean
|
||||||
minify: boolean
|
minify: boolean
|
||||||
sourceMap: boolean
|
sourceMap: boolean
|
||||||
externals: boolean
|
externals: boolean | NodeExternalsOptions
|
||||||
analyze: boolean
|
analyze: boolean
|
||||||
entry: string
|
entry: string
|
||||||
node: boolean
|
node: boolean
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { dirname, join, relative, resolve } from 'upath'
|
import { dirname, join, relative, resolve } from 'upath'
|
||||||
import { InputOptions, OutputOptions } from 'rollup'
|
import { InputOptions, OutputOptions } from 'rollup'
|
||||||
|
import defu from 'defu'
|
||||||
import { terser } from 'rollup-plugin-terser'
|
import { terser } from 'rollup-plugin-terser'
|
||||||
import commonjs from '@rollup/plugin-commonjs'
|
import commonjs from '@rollup/plugin-commonjs'
|
||||||
import nodeResolve from '@rollup/plugin-node-resolve'
|
import nodeResolve from '@rollup/plugin-node-resolve'
|
||||||
@ -51,6 +52,8 @@ export const getRollupConfig = (sigmaContext: SigmaContext) => {
|
|||||||
|
|
||||||
const env = un.env(nodePreset, builtinPreset, sigmaContext.env)
|
const env = un.env(nodePreset, builtinPreset, sigmaContext.env)
|
||||||
|
|
||||||
|
delete env.alias['node-fetch'] // FIX ME
|
||||||
|
|
||||||
if (sigmaContext.sourceMap) {
|
if (sigmaContext.sourceMap) {
|
||||||
env.polyfill.push('source-map-support/register')
|
env.polyfill.push('source-map-support/register')
|
||||||
}
|
}
|
||||||
@ -165,15 +168,27 @@ export const getRollupConfig = (sigmaContext: SigmaContext) => {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// External Plugin
|
const moduleDirectories = [
|
||||||
if (sigmaContext.externals) {
|
resolve(sigmaContext._nuxt.rootDir, 'node_modules'),
|
||||||
rollupConfig.plugins.push(externals({
|
resolve(MODULE_DIR, 'node_modules'),
|
||||||
relativeTo: sigmaContext.output.serverDir,
|
resolve(MODULE_DIR, '../node_modules'),
|
||||||
include: [
|
'node_modules'
|
||||||
sigmaContext._internal.runtimeDir,
|
|
||||||
...sigmaContext.middleware.map(m => m.handle)
|
|
||||||
]
|
]
|
||||||
}))
|
|
||||||
|
// 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
|
// https://github.com/rollup/plugins/tree/master/packages/node-resolve
|
||||||
@ -181,11 +196,7 @@ export const getRollupConfig = (sigmaContext: SigmaContext) => {
|
|||||||
extensions,
|
extensions,
|
||||||
preferBuiltins: true,
|
preferBuiltins: true,
|
||||||
rootDir: sigmaContext._nuxt.rootDir,
|
rootDir: sigmaContext._nuxt.rootDir,
|
||||||
moduleDirectories: [
|
moduleDirectories,
|
||||||
resolve(sigmaContext._nuxt.rootDir, 'node_modules'),
|
|
||||||
resolve(MODULE_DIR, 'node_modules'),
|
|
||||||
'node_modules'
|
|
||||||
],
|
|
||||||
mainFields: ['main'] // Force resolve CJS (@vue/runtime-core ssrUtils)
|
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 }) {
|
export interface NodeExternalsOptions {
|
||||||
return {
|
ignore?: string[]
|
||||||
name: 'externals',
|
outDir?: string
|
||||||
resolveId (source) {
|
trace?: boolean
|
||||||
if (
|
traceOptions?: NodeFileTraceOptions
|
||||||
source[0] === '.' || // Compile relative imports
|
moduleDirectories?: string[]
|
||||||
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 function externals (opts: NodeExternalsOptions): Plugin {
|
||||||
|
const resolvedExternals = {}
|
||||||
return {
|
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
|
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'
|
import chalk from 'chalk'
|
||||||
|
|
||||||
export async function printFSTree (dir) {
|
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 items = (await Promise.all(files.map(async (file) => {
|
||||||
const path = resolve(dir, file)
|
const path = resolve(dir, file)
|
||||||
@ -19,16 +19,27 @@ export async function printFSTree (dir) {
|
|||||||
let totalSize = 0
|
let totalSize = 0
|
||||||
let totalGzip = 0
|
let totalGzip = 0
|
||||||
|
|
||||||
|
let totalNodeModulesSize = 0
|
||||||
|
let totalNodeModulesGzip = 0
|
||||||
|
|
||||||
items.forEach((item, index) => {
|
items.forEach((item, index) => {
|
||||||
let dir = dirname(item.file)
|
let dir = dirname(item.file)
|
||||||
if (dir === '.') { dir = '' }
|
if (dir === '.') { dir = '' }
|
||||||
const rpath = relative(process.cwd(), item.path)
|
const rpath = relative(process.cwd(), item.path)
|
||||||
const treeChar = index === items.length - 1 ? '└─' : '├─'
|
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
|
totalSize += item.size
|
||||||
totalGzip += item.gzip
|
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