feat: support plug-and-play, typescript runtime and native modules (#8389)

Co-authored-by: Clark Du <clark.duxin@gmail.com>
This commit is contained in:
pooya parsa 2020-12-22 18:07:50 +01:00 committed by GitHub
parent 03384d3fbc
commit dec8f99fc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 523 additions and 470 deletions

View File

@ -3,7 +3,7 @@
"scripts": { "scripts": {
"build": "npm run nuxt -- build", "build": "npm run nuxt -- build",
"start": "npm run build && npm run nuxt -- start", "start": "npm run build && npm run nuxt -- start",
"nuxt": "node -r esm ../packages/cli/bin/nuxt-cli.js", "nuxt": "jiti ../packages/cli/bin/nuxt-cli.js",
"bench:stateless": "ab -c1 -n3000 http://127.0.0.1:3000/stateless", "bench:stateless": "ab -c1 -n3000 http://127.0.0.1:3000/stateless",
"bench:stateless-big": "ab -c1 -n500 http://127.0.0.1:3000/stateless-big" "bench:stateless-big": "ab -c1 -n500 http://127.0.0.1:3000/stateless-big"
} }

View File

@ -4,6 +4,8 @@ if (process.argv[2] !== 'start') {
process.argv.splice(2, 0, 'start') process.argv.splice(2, 0, 'start')
} }
global.__NUXT_PATHS__ = (global.__NUXT_PATHS__ || []).concat(__dirname)
const suffix = require('../package.json').name.includes('-edge') ? '-edge' : '' const suffix = require('../package.json').name.includes('-edge') ? '-edge' : ''
require('@nuxt/cli' + suffix).run() require('@nuxt/cli' + suffix).run()
.catch((error) => { .catch((error) => {

View File

@ -19,5 +19,19 @@ export default {
await pkg.writePackage() await pkg.writePackage()
} }
} },
ignoreUnused: [
// directly used by bin
'@nuxt/cli',
// discovered by config
'@nuxt/telemetry',
// vue-app externals for ssr
'node-fetch',
'vue',
'vue-client-only',
'vue-meta',
'vue-no-ssr',
'vue-router',
'vuex'
]
} }

View File

@ -1,5 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
global.__NUXT_PATHS__ = (global.__NUXT_PATHS__ || []).concat(__dirname)
const suffix = require('../package.json').name.includes('-edge') ? '-edge' : '' const suffix = require('../package.json').name.includes('-edge') ? '-edge' : ''
require('@nuxt/cli' + suffix).run() require('@nuxt/cli' + suffix).run()
.catch((error) => { .catch((error) => {

View File

@ -9,5 +9,13 @@ export default {
'README.md' 'README.md'
]) ])
} }
} },
ignoreUnused: [
// used by postinstall
'@nuxt/opencollective',
// discovered by config
'@nuxt/components',
'@nuxt/loading-screen',
'@nuxt/telemetry'
]
} }

View File

@ -48,7 +48,9 @@
} }
], ],
"main": "dist/nuxt.js", "main": "dist/nuxt.js",
"bin": "bin/nuxt.js", "bin": {
"nuxt": "./bin/nuxt.js"
},
"files": [ "files": [
"bin", "bin",
"dist", "dist",
@ -65,8 +67,7 @@
"@nuxt/generator": "2.14.12", "@nuxt/generator": "2.14.12",
"@nuxt/loading-screen": "^2.0.3", "@nuxt/loading-screen": "^2.0.3",
"@nuxt/opencollective": "^0.3.2", "@nuxt/opencollective": "^0.3.2",
"@nuxt/telemetry": "^1.3.0", "@nuxt/telemetry": "^1.3.0"
"@nuxt/webpack": "2.14.12"
}, },
"engines": { "engines": {
"node": ">=10.13.0", "node": ">=10.13.0",

View File

@ -1,4 +1,5 @@
export * from '@nuxt/core' export * from '@nuxt/core'
export * from '@nuxt/builder' export * from '@nuxt/builder'
export * from '@nuxt/generator' export * from '@nuxt/generator'
export { getWebpackConfig } from '@nuxt/cli' export { getWebpackConfig } from '@nuxt/cli'

View File

@ -12,18 +12,18 @@
"scripts": { "scripts": {
"audit": "improved-yarn-audit --ignore-dev-deps --min-severity moderate -e 1548", "audit": "improved-yarn-audit --ignore-dev-deps --min-severity moderate -e 1548",
"build": "yarn clean && yarn pkg", "build": "yarn clean && yarn pkg",
"changelog": "node -r esm scripts/changelog.js", "changelog": "jiti scripts/changelog.js",
"clean": "yarn clean:build && yarn clean:examples && yarn clean:test", "clean": "yarn clean:build && yarn clean:examples && yarn clean:test",
"clean:build": "rimraf distributions/*/dist packages/*/dist", "clean:build": "rimraf distributions/*/dist packages/*/dist",
"clean:examples": "rimraf examples/*/dist examples/*/.nuxt", "clean:examples": "rimraf examples/*/dist examples/*/.nuxt",
"clean:test": "rimraf test/fixtures/*/dist test/fixtures/*/.nuxt*/", "clean:test": "rimraf test/fixtures/*/dist test/fixtures/*/.nuxt*/",
"dev": "node -r esm ./scripts/dev.js", "dev": "jiti ./scripts/dev.js",
"postinstall": "lerna link && yarn dev", "postinstall": "lerna link && yarn dev",
"lint": "eslint --ext .js,.mjs,.vue .", "lint": "eslint --ext .js,.mjs,.vue .",
"lint:app": "eslint-multiplexer eslint --ignore-path packages/vue-app/template/.eslintignore 'test/fixtures/!(missing-plugin)/.nuxt!(-dev)/**' | eslint-multiplexer -b", "lint:app": "eslint-multiplexer eslint --ignore-path packages/vue-app/template/.eslintignore 'test/fixtures/!(missing-plugin)/.nuxt!(-dev)/**' | eslint-multiplexer -b",
"ls-lint": "npx @ls-lint/ls-lint", "ls-lint": "npx @ls-lint/ls-lint",
"nuxt": "node -r esm ./packages/cli/bin/nuxt-cli.js", "nuxt": "jiti ./packages/cli/bin/nuxt-cli.js",
"pkg": "node -r esm ./scripts/package", "pkg": "jiti ./scripts/package",
"test": "yarn test:fixtures && yarn test:dev && yarn test:unit && test:types", "test": "yarn test:fixtures && yarn test:dev && yarn test:unit && test:types",
"test:dev": "jest test/dev --forceExit", "test:dev": "jest test/dev --forceExit",
"test:e2e": "jest -i test/e2e --forceExit", "test:e2e": "jest -i test/e2e --forceExit",
@ -51,7 +51,6 @@
"cross-spawn": "^7.0.3", "cross-spawn": "^7.0.3",
"eslint": "^7.16.0", "eslint": "^7.16.0",
"eslint-multiplexer": "^2.0.0", "eslint-multiplexer": "^2.0.0",
"esm": "^3.2.25",
"execa": "^5.0.0", "execa": "^5.0.0",
"express": "^4.17.1", "express": "^4.17.1",
"finalhandler": "^1.1.2", "finalhandler": "^1.1.2",

View File

@ -4,14 +4,14 @@ const coreJsMeta = {
es6: 'es6', es6: 'es6',
es7: 'es7' es7: 'es7'
}, },
builtIns: '@babel/compat-data/corejs2-built-ins' builtIns: require.resolve('@babel/compat-data/corejs2-built-ins')
}, },
3: { 3: {
prefixes: { prefixes: {
es6: 'es', es6: 'es',
es7: 'es' es7: 'es'
}, },
builtIns: 'core-js-compat/data' builtIns: require.resolve('core-js-compat/data')
} }
} }

View File

@ -1,3 +1,7 @@
export default { export default {
build: true build: true,
ignoreUnused: [
// used for legacy _ in template context
'lodash'
]
} }

View File

@ -23,8 +23,7 @@
"pify": "^5.0.0", "pify": "^5.0.0",
"semver": "^7.3.4", "semver": "^7.3.4",
"serialize-javascript": "^5.0.1", "serialize-javascript": "^5.0.1",
"upath": "^2.0.1", "upath": "^2.0.1"
"url-polyfill": "^1.1.12"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

@ -8,13 +8,7 @@ import hash from 'hash-sum'
import pify from 'pify' import pify from 'pify'
import upath from 'upath' import upath from 'upath'
import semver from 'semver' import semver from 'semver'
import { debounce, omit, template, uniq, uniqBy } from 'lodash'
import debounce from 'lodash/debounce'
import omit from 'lodash/omit'
import template from 'lodash/template'
import uniq from 'lodash/uniq'
import uniqBy from 'lodash/uniqBy'
import { import {
r, r,
createRoutes, createRoutes,
@ -27,6 +21,9 @@ import {
TARGETS TARGETS
} from '@nuxt/utils' } from '@nuxt/utils'
import { template as VueAppTemplate } from '@nuxt/vue-app'
import { BundleBuilder as WebpackBuilder } from '@nuxt/webpack'
import Ignore from './ignore' import Ignore from './ignore'
import BuildContext from './context/build' import BuildContext from './context/build'
import TemplateContext from './context/template' import TemplateContext from './context/template'
@ -74,7 +71,7 @@ export default class Builder {
} }
// Resolve template // Resolve template
this.template = this.options.build.template || '@nuxt/vue-app' this.template = this.options.build.template || VueAppTemplate
if (typeof this.template === 'string') { if (typeof this.template === 'string') {
this.template = this.nuxt.resolver.requireModule(this.template).template this.template = this.nuxt.resolver.requireModule(this.template).template
} }
@ -96,7 +93,7 @@ export default class Builder {
const context = new BuildContext(this) const context = new BuildContext(this)
if (typeof BundleBuilder !== 'function') { if (typeof BundleBuilder !== 'function') {
({ BundleBuilder } = require('@nuxt/webpack')) BundleBuilder = WebpackBuilder
} }
return new BundleBuilder(context) return new BundleBuilder(context)

View File

@ -1,10 +1,10 @@
import hash from 'hash-sum' import hash from 'hash-sum'
import consola from 'consola' import consola from 'consola'
import uniqBy from 'lodash/uniqBy' import { uniqBy } from 'lodash'
import serialize from 'serialize-javascript' import serialize from 'serialize-javascript'
import devalue from '@nuxt/devalue' import devalue from '@nuxt/devalue'
import { r, wp, wChunk, serializeFunction, isFullStatic } from '@nuxt/utils' import { r, wp, wChunk, serializeFunction, isFullStatic, requireModule } from '@nuxt/utils'
export default class TemplateContext { export default class TemplateContext {
constructor (builder, options) { constructor (builder, options) {
@ -70,7 +70,7 @@ export default class TemplateContext {
get (target, prop) { get (target, prop) {
if (!lodash) { if (!lodash) {
consola.warn('Avoid using _ inside templates') consola.warn('Avoid using _ inside templates')
lodash = require('lodash') lodash = requireModule('lodash')
} }
return lodash[prop] return lodash[prop]
} }

View File

@ -17,7 +17,7 @@ export const createNuxt = () => ({
hook: jest.fn(), hook: jest.fn(),
callHook: jest.fn(), callHook: jest.fn(),
resolver: { resolver: {
requireModule: jest.fn(() => ({ template: 'builder-template' })), requireModule: jest.fn(),
resolveAlias: jest.fn(src => `resolveAlias(${src})`), resolveAlias: jest.fn(src => `resolveAlias(${src})`),
resolvePath: jest.fn(src => `resolvePath(${src})`) resolvePath: jest.fn(src => `resolvePath(${src})`)
} }

View File

@ -1,9 +1,11 @@
import consola from 'consola' import consola from 'consola'
import { template as VueAppTemplate } from '@nuxt/vue-app'
import { relativeTo, determineGlobals } from '@nuxt/utils' import { relativeTo, determineGlobals } from '@nuxt/utils'
import Builder from '../src/builder' import Builder from '../src/builder'
import { createNuxt } from './__utils__' import { createNuxt } from './__utils__'
jest.mock('@nuxt/vue-app')
jest.mock('@nuxt/utils') jest.mock('@nuxt/utils')
jest.mock('../src/ignore') jest.mock('../src/ignore')
@ -37,9 +39,7 @@ describe('builder: builder constructor', () => {
expect(builder._buildStatus).toEqual(1) expect(builder._buildStatus).toEqual(1)
expect(nuxt.resolver.requireModule).toBeCalledTimes(1) expect(builder.template).toBe(VueAppTemplate)
expect(nuxt.resolver.requireModule).toBeCalledWith('@nuxt/vue-app')
expect(builder.template).toEqual('builder-template')
expect(builder.bundleBuilder).toBe(bundleBuilder) expect(builder.bundleBuilder).toBe(bundleBuilder)
}) })
@ -112,6 +112,5 @@ describe('builder: builder constructor', () => {
const builder = new Builder(nuxt, bundleBuilder) const builder = new Builder(nuxt, bundleBuilder)
expect(builder.template).toBe(nuxt.options.build.template) expect(builder.template).toBe(nuxt.options.build.template)
expect(nuxt.resolver.requireModule).not.toBeCalled()
}) })
}) })

View File

@ -1,8 +1,8 @@
import path from 'path' import path from 'path'
import lodash from 'lodash'
import Glob from 'glob' import Glob from 'glob'
import fs from 'fs-extra' import fs from 'fs-extra'
import consola from 'consola' import consola from 'consola'
import template from 'lodash/template'
import { r, createRoutes, stripWhitespace } from '@nuxt/utils' import { r, createRoutes, stripWhitespace } from '@nuxt/utils'
import { BundleBuilder } from '@nuxt/webpack' import { BundleBuilder } from '@nuxt/webpack'
import Builder from '../src/builder' import Builder from '../src/builder'
@ -10,9 +10,12 @@ import TemplateContext from '../src/context/template'
import { createNuxt } from './__utils__' import { createNuxt } from './__utils__'
jest.mock('glob') jest.mock('glob')
jest.mock('lodash', () => ({
...jest.requireActual('lodash'),
template: jest.fn()
}))
jest.mock('pify', () => fn => fn) jest.mock('pify', () => fn => fn)
jest.mock('fs-extra') jest.mock('fs-extra')
jest.mock('lodash/template')
jest.mock('@nuxt/utils') jest.mock('@nuxt/utils')
jest.mock('../src/context/template', () => jest.fn()) jest.mock('../src/context/template', () => jest.fn())
jest.mock('../src/ignore', () => function () { jest.mock('../src/ignore', () => function () {
@ -373,7 +376,7 @@ describe('builder: builder generate', () => {
const builder = new Builder(nuxt, BundleBuilder) const builder = new Builder(nuxt, BundleBuilder)
builder.relativeToBuild = jest.fn() builder.relativeToBuild = jest.fn()
const templateFn = jest.fn(() => 'compiled content') const templateFn = jest.fn(() => 'compiled content')
template.mockImplementation(() => templateFn) lodash.template.mockImplementation(() => templateFn)
stripWhitespace.mockImplementation(content => `trim(${content})`) stripWhitespace.mockImplementation(content => `trim(${content})`)
const templateContext = { const templateContext = {
@ -403,10 +406,10 @@ describe('builder: builder generate', () => {
expect(fs.readFile).nthCalledWith(1, '/var/nuxt/src/foo.js', 'utf8') expect(fs.readFile).nthCalledWith(1, '/var/nuxt/src/foo.js', 'utf8')
expect(fs.readFile).nthCalledWith(2, '/var/nuxt/src/bar.js', 'utf8') expect(fs.readFile).nthCalledWith(2, '/var/nuxt/src/bar.js', 'utf8')
expect(fs.readFile).nthCalledWith(3, '/var/nuxt/src/baz.js', 'utf8') expect(fs.readFile).nthCalledWith(3, '/var/nuxt/src/baz.js', 'utf8')
expect(template).toBeCalledTimes(3) expect(lodash.template).toBeCalledTimes(3)
expect(template).nthCalledWith(1, 'readFile(/var/nuxt/src/foo.js, utf8)', templateContext.templateOptions) expect(lodash.template).nthCalledWith(1, 'readFile(/var/nuxt/src/foo.js, utf8)', templateContext.templateOptions)
expect(template).nthCalledWith(2, 'readFile(/var/nuxt/src/bar.js, utf8)', templateContext.templateOptions) expect(lodash.template).nthCalledWith(2, 'readFile(/var/nuxt/src/bar.js, utf8)', templateContext.templateOptions)
expect(template).nthCalledWith(3, 'readFile(/var/nuxt/src/baz.js, utf8)', templateContext.templateOptions) expect(lodash.template).nthCalledWith(3, 'readFile(/var/nuxt/src/baz.js, utf8)', templateContext.templateOptions)
expect(templateFn).toBeCalledTimes(3) expect(templateFn).toBeCalledTimes(3)
expect(templateFn).nthCalledWith(1, { expect(templateFn).nthCalledWith(1, {
...templateContext.templateVars, ...templateContext.templateVars,
@ -442,7 +445,7 @@ describe('builder: builder generate', () => {
const nuxt = createNuxt() const nuxt = createNuxt()
const builder = new Builder(nuxt, BundleBuilder) const builder = new Builder(nuxt, BundleBuilder)
builder.relativeToBuild = jest.fn() builder.relativeToBuild = jest.fn()
template.mockImplementation(() => { lodash.template.mockImplementation(() => {
throw new Error('compile failed') throw new Error('compile failed')
}) })

View File

@ -1,24 +1,25 @@
import path from 'path' import path from 'path'
import chokidar from 'chokidar' import chokidar from 'chokidar'
import upath from 'upath' import upath from 'upath'
import debounce from 'lodash/debounce' import { debounce } from 'lodash'
import { r, isString, isPureObject } from '@nuxt/utils' import { r, isString, isPureObject } from '@nuxt/utils'
import { BundleBuilder } from '@nuxt/webpack' import { BundleBuilder } from '@nuxt/webpack'
import Builder from '../src/builder' import Builder from '../src/builder'
import { createNuxt } from './__utils__' import { createNuxt } from './__utils__'
jest.mock('@nuxt/webpack')
jest.mock('lodash', () => ({
...jest.requireActual('lodash'),
debounce: jest.fn(fn => fn)
}))
jest.mock('chokidar', () => ({ jest.mock('chokidar', () => ({
watch: jest.fn().mockReturnThis(), watch: jest.fn().mockReturnThis(),
on: jest.fn().mockReturnThis(), on: jest.fn().mockReturnThis(),
close: jest.fn().mockReturnThis() close: jest.fn().mockReturnThis()
})) }))
jest.mock('upath', () => ({ normalizeSafe: jest.fn(src => src) })) jest.mock('upath', () => ({ normalizeSafe: jest.fn(src => src) }))
jest.mock('lodash/debounce', () => jest.fn(fn => fn))
jest.mock('@nuxt/utils') jest.mock('@nuxt/utils')
jest.mock('../src/ignore')
jest.mock('@nuxt/webpack') jest.mock('@nuxt/webpack')
jest.mock('../src/ignore')
describe('builder: builder watch', () => { describe('builder: builder watch', () => {
beforeEach(() => { beforeEach(() => {

View File

@ -6,7 +6,11 @@ import devalue from '@nuxt/devalue'
import { r, wp, wChunk, serializeFunction } from '@nuxt/utils' import { r, wp, wChunk, serializeFunction } from '@nuxt/utils'
import TemplateContext from '../../src/context/template' import TemplateContext from '../../src/context/template'
jest.mock('lodash', () => ({ test: 'test lodash', warn: 'only once' })) jest.mock('lodash', () => ({
...jest.requireActual('lodash'),
test: 'test lodash',
warn: 'only once'
}))
describe('builder: buildContext', () => { describe('builder: buildContext', () => {
const builder = { const builder = {

View File

@ -1,3 +1,5 @@
export default { export default {
build: true build: true,
ignoreUnused: ['crc'],
externals: ['crc/lib/crc32']
} }

View File

@ -20,13 +20,14 @@
"connect": "^3.7.0", "connect": "^3.7.0",
"consola": "^2.15.0", "consola": "^2.15.0",
"crc": "^3.8.0", "crc": "^3.8.0",
"defu": "^3.2.2",
"destr": "^1.0.1", "destr": "^1.0.1",
"esm": "^3.2.25",
"execa": "^5.0.0", "execa": "^5.0.0",
"exit": "^0.1.2", "exit": "^0.1.2",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"globby": "^11.0.1", "globby": "^11.0.1",
"hable": "^3.0.0", "hable": "^3.0.0",
"lodash": "^4.4.2",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"opener": "1.5.2", "opener": "1.5.2",
"pretty-bytes": "^5.4.1", "pretty-bytes": "^5.4.1",

View File

@ -1,6 +1,6 @@
import util from 'util' import util from 'util'
import consola from 'consola' import consola from 'consola'
import get from 'lodash/get' import { get } from 'lodash'
import { common } from '../options' import { common } from '../options'
export default { export default {

View File

@ -1,31 +1,18 @@
import path from 'path' import { requireModule } from '@nuxt/utils'
const localNodeModules = path.resolve(process.cwd(), 'node_modules') export const importModule = (id) => {
try {
// Prefer importing modules from local node_modules (for NPX and global bin) return Promise.resolve(requireModule(id))
async function _import (modulePath) { } catch (err) {
for (const mp of [ if (err.code === 'MODULE_NOT_FOUND') {
path.resolve(localNodeModules, modulePath), err.message = `Cannot import module '${id}'`
modulePath
]) {
try {
return await import(mp)
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') {
throw e
}
} }
return Promise.reject(err)
} }
const error = new Error(`Cannot import module '${modulePath}'`)
error.code = 'MODULE_NOT_FOUND'
throw error
} }
export const builder = () => _import('@nuxt/builder') export const builder = () => importModule('@nuxt/builder')
export const webpack = () => _import('@nuxt/webpack') export const webpack = () => importModule('@nuxt/webpack')
export const generator = () => _import('@nuxt/generator') export const generator = () => importModule('@nuxt/generator')
export const core = () => _import('@nuxt/core') export const core = () => importModule('@nuxt/core')
export const server = () => _import('@nuxt/server') export const server = () => importModule('@nuxt/server')
export const importModule = _import

View File

@ -2,6 +2,7 @@ import { existsSync } from 'fs'
import { resolve } from 'path' import { resolve } from 'path'
import execa from 'execa' import execa from 'execa'
import consola from 'consola' import consola from 'consola'
import { requireModule } from '@nuxt/utils'
import { name as pkgName } from '../package.json' import { name as pkgName } from '../package.json'
import NuxtCommand from './command' import NuxtCommand from './command'
import setup from './setup' import setup from './setup'
@ -12,7 +13,7 @@ export default async function run (_argv, hooks = {}) {
// Check for not installing both nuxt and nuxt-edge // Check for not installing both nuxt and nuxt-edge
const dupPkg = pkgName === '@nuxt/cli-edge' ? 'cli' : 'cli-edge' const dupPkg = pkgName === '@nuxt/cli-edge' ? 'cli' : 'cli-edge'
const dupPkgJSON = resolve(__dirname, '../..' /* dist/../.. */, dupPkg, 'package.json') const dupPkgJSON = resolve(__dirname, '../..' /* dist/../.. */, dupPkg, 'package.json')
if (existsSync(dupPkgJSON) && require(dupPkgJSON).name !== '@nuxt/' + dupPkg) { if (existsSync(dupPkgJSON) && requireModule(dupPkgJSON).name !== '@nuxt/' + dupPkg) {
consola.warn('Both `nuxt` and `nuxt-edge` dependencies are installed! Please choose one and remove the other one from dependencies.') consola.warn('Both `nuxt` and `nuxt-edge` dependencies are installed! Please choose one and remove the other one from dependencies.')
} }

View File

@ -1,5 +1,5 @@
import path from 'path' import path from 'path'
import defaultsDeep from 'lodash/defaultsDeep' import defu from 'defu'
import { loadNuxtConfig as _loadNuxtConfig, getDefaultNuxtConfig } from '@nuxt/config' import { loadNuxtConfig as _loadNuxtConfig, getDefaultNuxtConfig } from '@nuxt/config'
export async function loadNuxtConfig (argv, configContext) { export async function loadNuxtConfig (argv, configContext) {
@ -24,10 +24,10 @@ export async function loadNuxtConfig (argv, configContext) {
} }
// Server options // Server options
options.server = defaultsDeep({ options.server = defu({
port: argv.port || undefined, port: argv.port || null,
host: argv.hostname || undefined, host: argv.hostname || null,
socket: argv['unix-socket'] || undefined socket: argv['unix-socket'] || null
}, options.server || {}, getDefaultNuxtConfig().server) }, options.server || {}, getDefaultNuxtConfig().server)
return options return options

View File

@ -5,6 +5,7 @@ import connect from 'connect'
import serveStatic from 'serve-static' import serveStatic from 'serve-static'
import compression from 'compression' import compression from 'compression'
import { getNuxtConfig } from '@nuxt/config' import { getNuxtConfig } from '@nuxt/config'
import { requireModule } from '@nuxt/utils'
import { showBanner } from '../utils/banner' import { showBanner } from '../utils/banner'
import * as imports from '../imports' import * as imports from '../imports'
@ -16,7 +17,7 @@ export async function serve (cmd) {
try { try {
// overwrites with build config // overwrites with build config
const buildConfig = require(join(options.buildDir, 'nuxt/config.json')) const buildConfig = requireModule(join(options.buildDir, 'nuxt/config.json'))
options.target = buildConfig.target options.target = buildConfig.target
} catch (err) { } } catch (err) { }

View File

@ -2,7 +2,7 @@
exports[`webpack getWebpackConfig() 1`] = ` exports[`webpack getWebpackConfig() 1`] = `
"Object { "Object {
\\"loader\\": \\"vue-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-loader/lib/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"productionMode\\": true, \\"productionMode\\": true,
\\"transformAssetUrls\\": Object { \\"transformAssetUrls\\": Object {
@ -24,7 +24,7 @@ exports[`webpack nuxt webpack devtool 1`] = `
exports[`webpack nuxt webpack module.rules 1`] = ` exports[`webpack nuxt webpack module.rules 1`] = `
"Array [ "Array [
Object { Object {
\\"loader\\": \\"vue-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-loader/lib/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"productionMode\\": true, \\"productionMode\\": true,
\\"transformAssetUrls\\": Object { \\"transformAssetUrls\\": Object {
@ -90,13 +90,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"resourceQuery\\": /module/, \\"resourceQuery\\": /module/,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -107,7 +107,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -124,13 +124,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
Object { Object {
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -138,7 +138,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -161,13 +161,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"resourceQuery\\": /module/, \\"resourceQuery\\": /module/,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -178,7 +178,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -195,13 +195,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
Object { Object {
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -209,7 +209,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -232,13 +232,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"resourceQuery\\": /module/, \\"resourceQuery\\": /module/,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -249,7 +249,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -272,13 +272,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
Object { Object {
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -286,7 +286,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -315,13 +315,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"resourceQuery\\": /module/, \\"resourceQuery\\": /module/,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -332,7 +332,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -345,7 +345,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"sass-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/sass-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sassOptions\\": Object { \\"sassOptions\\": Object {
\\"indentedSyntax\\": true, \\"indentedSyntax\\": true,
@ -358,13 +358,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
Object { Object {
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -372,7 +372,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -385,7 +385,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"sass-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/sass-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sassOptions\\": Object { \\"sassOptions\\": Object {
\\"indentedSyntax\\": true, \\"indentedSyntax\\": true,
@ -404,13 +404,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"resourceQuery\\": /module/, \\"resourceQuery\\": /module/,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -421,7 +421,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -434,7 +434,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"sass-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/sass-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
@ -444,13 +444,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
Object { Object {
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -458,7 +458,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -471,7 +471,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"sass-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/sass-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
@ -487,13 +487,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"resourceQuery\\": /module/, \\"resourceQuery\\": /module/,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -504,7 +504,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -527,13 +527,13 @@ exports[`webpack nuxt webpack module.rules 1`] = `
Object { Object {
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"vue-style-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-style-loader/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"sourceMap\\": false, \\"sourceMap\\": false,
}, },
}, },
Object { Object {
\\"loader\\": \\"css-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/css-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"importLoaders\\": 2, \\"importLoaders\\": 2,
@ -541,7 +541,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
}, },
}, },
Object { Object {
\\"loader\\": \\"postcss-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/postcss-loader/src/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"order\\": \\"presetEnvAndCssnanoLast\\", \\"order\\": \\"presetEnvAndCssnanoLast\\",
\\"plugins\\": Array [ \\"plugins\\": Array [
@ -568,7 +568,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"test\\": /\\\\.(png|jpe?g|gif|svg|webp|avif)$/i, \\"test\\": /\\\\.(png|jpe?g|gif|svg|webp|avif)$/i,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"url-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/url-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"limit\\": 1000, \\"limit\\": 1000,
@ -581,7 +581,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"test\\": /\\\\.(woff2?|eot|ttf|otf)(\\\\?.*)?$/i, \\"test\\": /\\\\.(woff2?|eot|ttf|otf)(\\\\?.*)?$/i,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"url-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/url-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"limit\\": 1000, \\"limit\\": 1000,
@ -594,7 +594,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
\\"test\\": /\\\\.(webm|mp4|ogv)$/i, \\"test\\": /\\\\.(webm|mp4|ogv)$/i,
\\"use\\": Array [ \\"use\\": Array [
Object { Object {
\\"loader\\": \\"file-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/file-loader/dist/cjs.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"esModule\\": false, \\"esModule\\": false,
\\"name\\": \\"videos/[name].[contenthash:7].[ext]\\", \\"name\\": \\"videos/[name].[contenthash:7].[ext]\\",
@ -608,7 +608,7 @@ exports[`webpack nuxt webpack module.rules 1`] = `
exports[`webpack nuxt webpack module.rules loader=.*-loader 1`] = ` exports[`webpack nuxt webpack module.rules loader=.*-loader 1`] = `
"Object { "Object {
\\"loader\\": \\"vue-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-loader/lib/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"productionMode\\": true, \\"productionMode\\": true,
\\"transformAssetUrls\\": Object { \\"transformAssetUrls\\": Object {
@ -625,7 +625,7 @@ exports[`webpack nuxt webpack module.rules loader=.*-loader 1`] = `
exports[`webpack nuxt webpack module.rules loader=vue- 1`] = ` exports[`webpack nuxt webpack module.rules loader=vue- 1`] = `
"Object { "Object {
\\"loader\\": \\"vue-loader\\", \\"loader\\": \\"<nuxtDir>/node_modules/vue-loader/lib/index.js\\",
\\"options\\": Object { \\"options\\": Object {
\\"productionMode\\": true, \\"productionMode\\": true,
\\"transformAssetUrls\\": Object { \\"transformAssetUrls\\": Object {

View File

@ -17,8 +17,8 @@
"defu": "^3.2.2", "defu": "^3.2.2",
"destr": "^1.0.1", "destr": "^1.0.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"esm": "^3.2.25",
"jiti": "^0.1.17", "jiti": "^0.1.17",
"lodash": "^4.17.20",
"rc9": "^1.2.0", "rc9": "^1.2.0",
"std-env": "^2.2.1" "std-env": "^2.2.1"
}, },

View File

@ -1,4 +1,4 @@
import capitalize from 'lodash/capitalize' import { capitalize } from 'lodash'
import env from 'std-env' import env from 'std-env'
import { TARGETS } from '@nuxt/utils' import { TARGETS } from '@nuxt/utils'

View File

@ -4,28 +4,28 @@ import defu from 'defu'
import consola from 'consola' import consola from 'consola'
import dotenv from 'dotenv' import dotenv from 'dotenv'
import { clearRequireCache, scanRequireTree } from '@nuxt/utils' import { clearRequireCache, scanRequireTree } from '@nuxt/utils'
import esm from 'esm' import jiti from 'jiti'
import _createRequire from 'create-require' import _createRequire from 'create-require'
import destr from 'destr' import destr from 'destr'
import * as rc from 'rc9' import * as rc from 'rc9'
import { defaultNuxtConfigFile } from './config' import { defaultNuxtConfigFile } from './config'
const isJest = typeof jest !== 'undefined' const isJest = typeof jest !== 'undefined'
const _require = isJest ? _createRequire(__filename) : jiti(__filename)
export async function loadNuxtConfig ({ export async function loadNuxtConfig ({
rootDir = '.', rootDir = '.',
envConfig = {}, envConfig = {},
configFile = defaultNuxtConfigFile, configFile = defaultNuxtConfigFile,
configContext = {}, configContext = {},
configOverrides = {}, configOverrides = {}
createRequire = module => isJest ? _createRequire(module.filename) : esm(module, { cache: false })
} = {}) { } = {}) {
rootDir = path.resolve(rootDir) rootDir = path.resolve(rootDir)
let options = {} let options = {}
try { try {
configFile = require.resolve(path.resolve(rootDir, configFile)) configFile = _require.resolve(path.resolve(rootDir, configFile))
} catch (e) { } catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') { if (e.code !== 'MODULE_NOT_FOUND') {
throw (e) throw (e)
@ -56,7 +56,6 @@ export async function loadNuxtConfig ({
if (configFile) { if (configFile) {
// Clear cache // Clear cache
clearRequireCache(configFile) clearRequireCache(configFile)
const _require = createRequire(module)
options = _require(configFile) || {} options = _require(configFile) || {}
if (options.default) { if (options.default) {
options = options.default options = options.default

View File

@ -1,9 +1,7 @@
import path from 'path' import path from 'path'
import fs from 'fs' import fs from 'fs'
import defaultsDeep from 'lodash/defaultsDeep' import { defaultsDeep, pick, uniq } from 'lodash'
import defu from 'defu' import defu from 'defu'
import pick from 'lodash/pick'
import uniq from 'lodash/uniq'
import consola from 'consola' import consola from 'consola'
import destr from 'destr' import destr from 'destr'
import { TARGETS, MODES, guardDir, isNonEmptyString, isPureObject, isUrl, getMainModule, urlJoin, getPKG } from '@nuxt/utils' import { TARGETS, MODES, guardDir, isNonEmptyString, isPureObject, isUrl, getMainModule, urlJoin, getPKG } from '@nuxt/utils'
@ -465,20 +463,22 @@ export function getNuxtConfig (_options) {
staticAssets.versionBase = urlJoin(staticAssets.base, staticAssets.version) staticAssets.versionBase = urlJoin(staticAssets.base, staticAssets.version)
} }
// createRequire factory // createRequire
if (options.createRequire === undefined) { const isJest = typeof jest !== 'undefined'
const isJest = typeof jest !== 'undefined' const defaultCreateRequire = isJest ? 'native' : 'jiti'
options.createRequire = isJest ? false : 'esm'
} options.createRequire = process.env.NUXT_CREATE_REQUIRE || options.createRequire || defaultCreateRequire
if (options.createRequire === 'esm') {
const esm = require('esm') if (options.createRequire === 'native') {
options.createRequire = module => esm(module, { cache: false }) const createRequire = require('create-require')
options.createRequire = p => createRequire(typeof p === 'string' ? p : p.filename)
} else if (options.createRequire === 'jiti') { } else if (options.createRequire === 'jiti') {
const jiti = require('jiti') const jiti = require('jiti')
options.createRequire = module => jiti(module.filename) options.createRequire = p => jiti(typeof p === 'string' ? p : p.filename)
} else if (typeof options.createRequire !== 'function') { } else if (typeof options.createRequire !== 'function') {
const createRequire = require('create-require') throw new TypeError(
options.createRequire = module => createRequire(module.filename) `Unsupported createRequire value ${options.createRequire}! Possible values: "native", "jiti", <Function>`
)
} }
// Indicator // Indicator

View File

@ -9,17 +9,14 @@
], ],
"dependencies": { "dependencies": {
"@nuxt/config": "2.14.12", "@nuxt/config": "2.14.12",
"@nuxt/devalue": "^1.2.4",
"@nuxt/server": "2.14.12", "@nuxt/server": "2.14.12",
"@nuxt/utils": "2.14.12", "@nuxt/utils": "2.14.12",
"@nuxt/vue-renderer": "2.14.12",
"consola": "^2.15.0", "consola": "^2.15.0",
"debug": "^4.2.0", "create-require": "^1.1.1",
"esm": "^3.2.25",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"hable": "^3.0.0", "hable": "^3.0.0",
"hash-sum": "^2.0.0", "hash-sum": "^2.0.0",
"std-env": "^2.2.1" "lodash": "^4.17.20"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

@ -121,11 +121,13 @@ export default class ModuleContainer {
) )
} }
requireModule (moduleOpts) { requireModule (moduleOpts, { requirePath } = {}) {
return this.addModule(moduleOpts) return this.addModule(moduleOpts, undefined, { requirePath })
} }
async addModule (moduleOpts) { async addModule (moduleOpts, arg2, arg3) {
// Arg2 was previously used for requireOnce which is ignored now
const { requirePath } = { ...arg2, ...arg3 }
let src let src
let options let options
let handler let handler
@ -154,7 +156,7 @@ export default class ModuleContainer {
// Resolve handler // Resolve handler
if (!handler) { if (!handler) {
try { try {
handler = this.nuxt.resolver.requireModule(src, { useESM: true }) handler = this.nuxt.resolver.requireModule(src, { requirePath })
} catch (error) { } catch (error) {
if (error.code !== 'MODULE_NOT_FOUND') { if (error.code !== 'MODULE_NOT_FOUND') {
throw error throw error

View File

@ -1,5 +1,5 @@
import isPlainObject from 'lodash/isPlainObject' import { isPlainObject } from 'lodash'
import consola from 'consola' import consola from 'consola'
import Hookable from 'hable' import Hookable from 'hable'

View File

@ -1,6 +1,7 @@
import { resolve, join } from 'path' import { resolve, join } from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import consola from 'consola' import consola from 'consola'
import createRequire from 'create-require'
import { import {
startsWithRootAlias, startsWithRootAlias,
@ -20,23 +21,20 @@ export default class Resolver {
this.resolveModule = this.resolveModule.bind(this) this.resolveModule = this.resolveModule.bind(this)
this.requireModule = this.requireModule.bind(this) this.requireModule = this.requireModule.bind(this)
const { createRequire } = this.options this._createRequire = this.options.createRequire || createRequire
this._require = createRequire ? createRequire(module) : module.require this._require = this._createRequire(__filename)
this._resolve = require.resolve
} }
resolveModule (path) { resolveModule (path, { requirePath } = {}) {
try { try {
return this._resolve(path, { return this._require.resolve(path, {
paths: this.options.modulesDir paths: [
requirePath || __dirname,
...[].concat(this.options.modulesDir)
]
}) })
} catch (error) { } catch (error) {
if (error.code !== 'MODULE_NOT_FOUND') { if (error.code !== 'MODULE_NOT_FOUND') {
// TODO: remove after https://github.com/facebook/jest/pull/8487 released
if (process.env.NODE_ENV === 'test' && error.message.startsWith('Cannot resolve module')) {
return
}
throw error throw error
} }
} }
@ -54,7 +52,7 @@ export default class Resolver {
return resolve(this.options.srcDir, path) return resolve(this.options.srcDir, path)
} }
resolvePath (path, { alias, isAlias = alias, module, isModule = module, isStyle } = {}) { resolvePath (path, { alias, isAlias = alias, module, isModule = module, isStyle, requirePath } = {}) {
// TODO: Remove in Nuxt 3 // TODO: Remove in Nuxt 3
if (alias) { if (alias) {
consola.warn('Using alias is deprecated and will be removed in Nuxt 3. Use `isAlias` instead.') consola.warn('Using alias is deprecated and will be removed in Nuxt 3. Use `isAlias` instead.')
@ -72,7 +70,7 @@ export default class Resolver {
// Try to resolve it as a regular module // Try to resolve it as a regular module
if (isModule !== false) { if (isModule !== false) {
resolvedPath = this.resolveModule(path) resolvedPath = this.resolveModule(path, { requirePath })
} }
// Try to resolve alias // Try to resolve alias
@ -119,7 +117,7 @@ export default class Resolver {
throw new Error(`Cannot resolve "${path}" from "${resolvedPath}"`) throw new Error(`Cannot resolve "${path}" from "${resolvedPath}"`)
} }
requireModule (path, { esm, useESM = esm, alias, isAlias = alias, intropDefault, interopDefault = intropDefault } = {}) { requireModule (path, { alias, isAlias = alias, intropDefault, interopDefault = intropDefault, requirePath } = {}) {
let resolvedPath = path let resolvedPath = path
let requiredModule let requiredModule
@ -130,15 +128,12 @@ export default class Resolver {
if (alias) { if (alias) {
consola.warn('Using alias is deprecated and will be removed in Nuxt 3. Use `isAlias` instead.') consola.warn('Using alias is deprecated and will be removed in Nuxt 3. Use `isAlias` instead.')
} }
if (esm) {
consola.warn('Using esm is deprecated and will be removed in Nuxt 3. Use `useESM` instead.')
}
let lastError let lastError
// Try to resolve path // Try to resolve path
try { try {
resolvedPath = this.resolvePath(path, { isAlias }) resolvedPath = this.resolvePath(path, { isAlias, requirePath })
} catch (e) { } catch (e) {
lastError = e lastError = e
} }
@ -151,18 +146,10 @@ export default class Resolver {
clearRequireCache(resolvedPath) clearRequireCache(resolvedPath)
} }
// By default use esm only for js,mjs files outside of node_modules
if (useESM === undefined) {
useESM = !isExternal && /.(js|mjs)$/.test(resolvedPath)
}
// Try to require // Try to require
try { try {
if (useESM) { const _require = requirePath ? this._createRequire(requirePath) : this._require
requiredModule = this._require(resolvedPath) requiredModule = _require(resolvedPath)
} else {
requiredModule = require(resolvedPath)
}
} catch (e) { } catch (e) {
lastError = e lastError = e
} }

View File

@ -318,7 +318,7 @@ describe('core: module', () => {
module.requireModule(moduleOpts) module.requireModule(moduleOpts)
expect(module.addModule).toBeCalledTimes(1) expect(module.addModule).toBeCalledTimes(1)
expect(module.addModule).toBeCalledWith(moduleOpts) expect(module.addModule).toBeCalledWith(moduleOpts, undefined, { requirePath: undefined })
}) })
test('should add string module', async () => { test('should add string module', async () => {
@ -332,7 +332,7 @@ describe('core: module', () => {
const result = await module.addModule('moduleTest') const result = await module.addModule('moduleTest')
expect(requireModule).toBeCalledTimes(1) expect(requireModule).toBeCalledTimes(1)
expect(requireModule).toBeCalledWith('moduleTest', { useESM: true }) expect(requireModule).toBeCalledWith('moduleTest', { requirePath: undefined })
expect(module.requiredModules).toEqual({ expect(module.requiredModules).toEqual({
moduleTest: { moduleTest: {
handler: expect.any(Function), handler: expect.any(Function),
@ -381,7 +381,7 @@ describe('core: module', () => {
const result = await module.addModule(['moduleTest', { test: true }]) const result = await module.addModule(['moduleTest', { test: true }])
expect(requireModule).toBeCalledTimes(1) expect(requireModule).toBeCalledTimes(1)
expect(requireModule).toBeCalledWith('moduleTest', { useESM: true }) expect(requireModule).toBeCalledWith('moduleTest', { requirePath: undefined })
expect(module.requiredModules).toEqual({ expect(module.requiredModules).toEqual({
moduleTest: { moduleTest: {
handler: expect.any(Function), handler: expect.any(Function),

View File

@ -5,13 +5,14 @@ import { startsWithRootAlias, startsWithSrcAlias } from '@nuxt/utils'
import Resolver from '../src/resolver' import Resolver from '../src/resolver'
jest.mock('esm', () => jest.fn(() => jest.fn()))
jest.mock('fs-extra') jest.mock('fs-extra')
jest.mock('@nuxt/utils') jest.mock('@nuxt/utils')
jest.spyOn(path, 'join') jest.spyOn(path, 'join')
jest.spyOn(path, 'resolve') jest.spyOn(path, 'resolve')
const modulesDir = path.resolve(__dirname, './__modules__')
describe.posix('core: resolver', () => { describe.posix('core: resolver', () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks() jest.clearAllMocks()
@ -33,40 +34,22 @@ describe.posix('core: resolver', () => {
test('should call require.resolve in resolveModule', () => { test('should call require.resolve in resolveModule', () => {
const resolver = new Resolver({ const resolver = new Resolver({
options: { modulesDir: '/var/nuxt/node_modules' } options: { modulesDir }
}) })
const resolve = resolver._resolve = jest.fn(() => '/var/nuxt/resolver/module')
const modulePath = resolver.resolveModule('/var/nuxt/resolver') const modulePath = resolver.resolveModule('__resolver__')
expect(modulePath).toEqual('/var/nuxt/resolver/module') expect(modulePath).toEqual(path.resolve(modulesDir, './__resolver__.js'))
expect(resolve).toBeCalledTimes(1)
expect(resolve).toBeCalledWith('/var/nuxt/resolver', { paths: '/var/nuxt/node_modules' })
}) })
test('should return undefined when module is not found', () => { test('should return undefined when module is not found', () => {
const resolver = new Resolver({ const resolver = new Resolver({
options: { modulesDir: '/var/nuxt/node_modules' } options: { modulesDir }
})
const resolve = resolver._resolve = jest.fn(() => {
const err = new Error()
err.code = 'MODULE_NOT_FOUND'
throw err
}) })
const modulePath = resolver.resolveModule('/var/nuxt/resolver') const modulePath = resolver.resolveModule('non-exist-module')
expect(modulePath).toBeUndefined() expect(modulePath).toBeUndefined()
expect(resolve).toBeCalledTimes(1)
})
test('should throw error when require.resolve failed', () => {
const resolver = new Resolver({
options: { modulesDir: '/var/nuxt/node_modules' }
})
resolver._resolve = jest.fn(() => { throw new Error('resolve failed') })
expect(() => resolver.resolveModule('/var/nuxt/resolver')).toThrow('resolve failed')
}) })
test('should resolve root alias', () => { test('should resolve root alias', () => {
@ -380,18 +363,6 @@ describe.posix('core: resolver', () => {
expect(resolvedModule).toEqual({ default: 'resolved module' }) expect(resolvedModule).toEqual({ default: 'resolved module' })
}) })
test('should require common module', () => {
const resolver = new Resolver({
options: {}
})
resolver.resolvePath = jest.fn(() => 'path')
resolver._require = jest.fn(() => ({ default: 'resolved module' }))
const resolvedModule = resolver.requireModule('path', { useESM: false })
expect(resolvedModule).toBe(path)
})
test('should throw error if resolvePath failed', () => { test('should throw error if resolvePath failed', () => {
const resolver = new Resolver({ const resolver = new Resolver({
options: {} options: {}
@ -444,11 +415,6 @@ describe.posix('core: resolver', () => {
}) })
resolver.resolvePath = jest.fn().mockReturnValue('/var/nuxt/resolver/file.js') resolver.resolvePath = jest.fn().mockReturnValue('/var/nuxt/resolver/file.js')
resolver._require = jest.fn() resolver._require = jest.fn()
resolver.requireModule('/var/nuxt/resolver/file.js', { esm: true })
const warnMsg = 'Using esm is deprecated and will be removed in Nuxt 3. Use `useESM` instead.'
expect(consola.warn).toBeCalledTimes(1)
expect(consola.warn).toBeCalledWith(warnMsg)
}) })
}) })
}) })

View File

@ -11,6 +11,7 @@
"@nuxt/utils": "2.14.12", "@nuxt/utils": "2.14.12",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"consola": "^2.15.0", "consola": "^2.15.0",
"defu": "^3.2.2",
"devalue": "^2.0.1", "devalue": "^2.0.1",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"html-minifier": "^4.0.0", "html-minifier": "^4.0.0",

View File

@ -7,7 +7,7 @@ import defu from 'defu'
import htmlMinifier from 'html-minifier' import htmlMinifier from 'html-minifier'
import { parse } from 'node-html-parser' import { parse } from 'node-html-parser'
import { isFullStatic, flatRoutes, isString, isUrl, promisifyRoute, urlJoin, waitFor } from '@nuxt/utils' import { isFullStatic, flatRoutes, isString, isUrl, promisifyRoute, urlJoin, waitFor, requireModule } from '@nuxt/utils'
export default class Generator { export default class Generator {
constructor (nuxt, builder) { constructor (nuxt, builder) {
@ -153,14 +153,14 @@ export default class Generator {
getBuildConfig () { getBuildConfig () {
try { try {
return require(path.join(this.options.buildDir, 'nuxt/config.json')) return requireModule(path.join(this.options.buildDir, 'nuxt/config.json'))
} catch (err) { } catch (err) {
return null return null
} }
} }
getAppRoutes () { getAppRoutes () {
return require(path.join(this.options.buildDir, 'routes.json')) return requireModule(path.join(this.options.buildDir, 'routes.json'))
} }
async generateRoutes (routes) { async generateRoutes (routes) {
@ -382,8 +382,9 @@ export default class Generator {
let fileName let fileName
if (this.options.generate.subFolders) { if (this.options.generate.subFolders) {
fileName = path.join(route, path.sep, 'index.html') // /about -> /about/index.html fileName = route === '/404'
fileName = fileName === '/404/index.html' ? '/404.html' : fileName // /404 -> /404.html ? path.join(path.sep, '404.html') // /404 -> /404.html
: path.join(route, path.sep, 'index.html') // /about -> /about/index.html
} else { } else {
const normalizedRoute = route.replace(/\/$/, '') const normalizedRoute = route.replace(/\/$/, '')
fileName = route.length > 1 ? path.join(path.sep, normalizedRoute + '.html') : path.join(path.sep, 'index.html') fileName = route.length > 1 ? path.join(path.sep, normalizedRoute + '.html') : path.join(path.sep, 'index.html')

View File

@ -1,3 +1,10 @@
import { resolve } from 'path'
import env from 'std-env'
const isWin = env.windows
const rootDir = isWin ? 'C:\\nuxt' : '/var/nuxt'
export const createNuxt = () => ({ export const createNuxt = () => ({
ready: jest.fn(), ready: jest.fn(),
callHook: jest.fn(), callHook: jest.fn(),
@ -6,11 +13,11 @@ export const createNuxt = () => ({
}, },
options: { options: {
mode: 'universal', mode: 'universal',
srcDir: '/var/nuxt/src', srcDir: resolve(rootDir, 'src'),
buildDir: '/var/nuxt/build', buildDir: resolve(rootDir, 'build'),
generate: { dir: '/var/nuxt/generate' }, generate: { dir: resolve(rootDir, 'generate') },
build: { publicPath: '__public' }, build: { publicPath: '__public' },
dir: { static: '/var/nuxt/static' }, dir: { static: resolve(rootDir, 'static') },
render: {} render: {}
} }
}) })

View File

@ -1,4 +1,3 @@
import path from 'path'
import chalk from 'chalk' import chalk from 'chalk'
import consola from 'consola' import consola from 'consola'
import fsExtra from 'fs-extra' import fsExtra from 'fs-extra'
@ -7,7 +6,6 @@ import { waitFor } from '@nuxt/utils'
import Generator from '../src/generator' import Generator from '../src/generator'
import { createNuxt } from './__utils__' import { createNuxt } from './__utils__'
jest.mock('path')
jest.mock('chalk', () => ({ jest.mock('chalk', () => ({
red: jest.fn(str => `red:${str}`), red: jest.fn(str => `red:${str}`),
yellow: jest.fn(str => `yellow:${str}`), yellow: jest.fn(str => `yellow:${str}`),
@ -17,17 +15,6 @@ jest.mock('fs-extra')
jest.mock('@nuxt/utils') jest.mock('@nuxt/utils')
describe('generator: generate routes', () => { describe('generator: generate routes', () => {
const sep = path.sep
beforeAll(() => {
path.sep = '[sep]'
path.join.mockImplementation((...args) => `join(${args.join(', ')})`)
})
afterAll(() => {
path.sep = sep
})
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks() jest.clearAllMocks()
}) })
@ -147,25 +134,28 @@ grey:bar failed`)
const nuxt = createNuxt() const nuxt = createNuxt()
nuxt.options.generate.fallback = 'fallback.html' nuxt.options.generate.fallback = 'fallback.html'
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
fsExtra.exists.mockReturnValueOnce(false) fsExtra.exists.mockReturnValueOnce(false)
await generator.afterGenerate() await generator.afterGenerate()
expect(path.join).toBeCalledTimes(1)
expect(path.join).toBeCalledWith(generator.distPath, 'fallback.html')
expect(fsExtra.exists).toBeCalledTimes(1) expect(fsExtra.exists).toBeCalledTimes(1)
expect(fsExtra.exists).toBeCalledWith(`join(${generator.distPath}, fallback.html)`) expect(fsExtra.exists.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/fallback.html',
'C:\\nuxt\\generate\\fallback.html'
)
expect(nuxt.server.renderRoute).toBeCalledTimes(1) expect(nuxt.server.renderRoute).toBeCalledTimes(1)
expect(nuxt.server.renderRoute).toBeCalledWith('/', { spa: true }) expect(nuxt.server.renderRoute).toBeCalledWith('/', { spa: true })
expect(fsExtra.writeFile).toBeCalledTimes(1) expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile).toBeCalledWith(`join(${generator.distPath}, fallback.html)`, 'rendered html', 'utf8') expect(fsExtra.writeFile).toBeCalledWith(expect.any(String), 'rendered html', 'utf8')
expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/fallback.html',
'C:\\nuxt\\generate\\fallback.html'
)
}) })
test('should disable writing fallback if fallback is empty or not string', async () => { test('should disable writing fallback if fallback is empty or not string', async () => {
const nuxt = createNuxt() const nuxt = createNuxt()
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
nuxt.options.generate.fallback = '' nuxt.options.generate.fallback = ''
await generator.afterGenerate() await generator.afterGenerate()
@ -173,7 +163,6 @@ grey:bar failed`)
nuxt.options.generate.fallback = jest.fn() nuxt.options.generate.fallback = jest.fn()
await generator.afterGenerate() await generator.afterGenerate()
expect(path.join).not.toBeCalled()
expect(fsExtra.exists).not.toBeCalled() expect(fsExtra.exists).not.toBeCalled()
expect(nuxt.server.renderRoute).not.toBeCalled() expect(nuxt.server.renderRoute).not.toBeCalled()
expect(fsExtra.writeFile).not.toBeCalled() expect(fsExtra.writeFile).not.toBeCalled()
@ -183,15 +172,15 @@ grey:bar failed`)
const nuxt = createNuxt() const nuxt = createNuxt()
nuxt.options.generate.fallback = 'fallback.html' nuxt.options.generate.fallback = 'fallback.html'
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
fsExtra.exists.mockReturnValueOnce(true) fsExtra.exists.mockReturnValueOnce(true)
await generator.afterGenerate() await generator.afterGenerate()
expect(path.join).toBeCalledTimes(1)
expect(path.join).toBeCalledWith(generator.distPath, 'fallback.html')
expect(fsExtra.exists).toBeCalledTimes(1) expect(fsExtra.exists).toBeCalledTimes(1)
expect(fsExtra.exists).toBeCalledWith(`join(${generator.distPath}, fallback.html)`) expect(fsExtra.exists.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/fallback.html',
'C:\\nuxt\\generate\\fallback.html'
)
expect(nuxt.server.renderRoute).not.toBeCalled() expect(nuxt.server.renderRoute).not.toBeCalled()
expect(fsExtra.writeFile).not.toBeCalled() expect(fsExtra.writeFile).not.toBeCalled()
}) })
@ -199,7 +188,6 @@ grey:bar failed`)
test('should disable writing fallback if fallback is empty or not string', async () => { test('should disable writing fallback if fallback is empty or not string', async () => {
const nuxt = createNuxt() const nuxt = createNuxt()
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
nuxt.options.generate.fallback = '' nuxt.options.generate.fallback = ''
await generator.afterGenerate() await generator.afterGenerate()
@ -207,7 +195,6 @@ grey:bar failed`)
nuxt.options.generate.fallback = jest.fn() nuxt.options.generate.fallback = jest.fn()
await generator.afterGenerate() await generator.afterGenerate()
expect(path.join).not.toBeCalled()
expect(fsExtra.exists).not.toBeCalled() expect(fsExtra.exists).not.toBeCalled()
expect(fsExtra.writeFile).not.toBeCalled() expect(fsExtra.writeFile).not.toBeCalled()
}) })

View File

@ -1,4 +1,3 @@
import path from 'path'
import consola from 'consola' import consola from 'consola'
import fsExtra from 'fs-extra' import fsExtra from 'fs-extra'
import { flatRoutes, isString, isUrl, promisifyRoute } from '@nuxt/utils' import { flatRoutes, isString, isUrl, promisifyRoute } from '@nuxt/utils'
@ -6,15 +5,12 @@ import { flatRoutes, isString, isUrl, promisifyRoute } from '@nuxt/utils'
import Generator from '../src/generator' import Generator from '../src/generator'
import { createNuxt, hookCalls } from './__utils__' import { createNuxt, hookCalls } from './__utils__'
jest.mock('path')
jest.mock('fs-extra') jest.mock('fs-extra')
jest.mock('@nuxt/utils') jest.mock('@nuxt/utils')
describe('generator: initialize', () => { describe('generator: initialize', () => {
beforeAll(() => { beforeAll(() => {
isString.mockImplementation(str => typeof str === 'string') isString.mockImplementation(str => typeof str === 'string')
path.join.mockImplementation((...args) => `join(${args.join(', ')})`)
path.resolve.mockImplementation((...args) => `resolve(${args.join(', ')})`)
}) })
beforeEach(() => { beforeEach(() => {
@ -34,10 +30,22 @@ describe('generator: initialize', () => {
expect(generator.nuxt).toBe(nuxt) expect(generator.nuxt).toBe(nuxt)
expect(generator.options).toBe(nuxt.options) expect(generator.options).toBe(nuxt.options)
expect(generator.builder).toBe(builder) expect(generator.builder).toBe(builder)
expect(generator.staticRoutes).toEqual('resolve(/var/nuxt/src, /var/nuxt/static)') expect(generator.staticRoutes).toBePath(
expect(generator.srcBuiltPath).toBe('resolve(/var/nuxt/build, dist, client)') '/var/nuxt/static',
expect(generator.distPath).toBe('/var/nuxt/generate') 'C:\\nuxt\\static'
expect(generator.distNuxtPath).toBe('join(/var/nuxt/generate, )') )
expect(generator.srcBuiltPath).toBePath(
'/var/nuxt/build/dist/client',
'C:\\nuxt\\build\\dist\\client'
)
expect(generator.distPath).toBePath(
'/var/nuxt/generate',
'C:\\nuxt\\generate'
)
expect(generator.distNuxtPath).toBePath(
'/var/nuxt/generate',
'C:\\nuxt\\generate'
)
}) })
test('should append publicPath to distPath if publicPath is not url', () => { test('should append publicPath to distPath if publicPath is not url', () => {
@ -50,7 +58,10 @@ describe('generator: initialize', () => {
const builder = jest.fn() const builder = jest.fn()
const generator = new Generator(nuxt, builder) const generator = new Generator(nuxt, builder)
expect(generator.distNuxtPath).toBe('join(/var/nuxt/generate, __public)') expect(generator.distNuxtPath).toBePath(
'/var/nuxt/generate/__public',
'C:\\nuxt\\generate\\__public'
)
}) })
test('should initiate with build and init by default', async () => { test('should initiate with build and init by default', async () => {
@ -172,8 +183,6 @@ describe('generator: initialize', () => {
const nuxt = createNuxt() const nuxt = createNuxt()
nuxt.options.generate.fallback = 'fallback.html' nuxt.options.generate.fallback = 'fallback.html'
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
path.resolve.mockClear()
fsExtra.exists.mockReturnValueOnce(false) fsExtra.exists.mockReturnValueOnce(false)
await generator.initDist() await generator.initDist()
@ -185,10 +194,11 @@ describe('generator: initialize', () => {
expect(fsExtra.exists).toBeCalledWith(generator.staticRoutes) expect(fsExtra.exists).toBeCalledWith(generator.staticRoutes)
expect(fsExtra.copy).toBeCalledTimes(1) expect(fsExtra.copy).toBeCalledTimes(1)
expect(fsExtra.copy).toBeCalledWith(generator.srcBuiltPath, generator.distNuxtPath) expect(fsExtra.copy).toBeCalledWith(generator.srcBuiltPath, generator.distNuxtPath)
expect(path.resolve).toBeCalledTimes(1)
expect(path.resolve).toBeCalledWith(generator.distPath, '.nojekyll')
expect(fsExtra.writeFile).toBeCalledTimes(1) expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile).toBeCalledWith(`resolve(${generator.distPath}, .nojekyll)`, '') expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/.nojekyll',
'C:\\nuxt\\generate\\.nojekyll'
)
expect(hookCalls(nuxt, 'generate:distCopied')[0][0]).toMatchObject(generator) expect(hookCalls(nuxt, 'generate:distCopied')[0][0]).toMatchObject(generator)
}) })

View File

@ -1,4 +1,3 @@
import path from 'path'
import consola from 'consola' import consola from 'consola'
import fsExtra from 'fs-extra' import fsExtra from 'fs-extra'
import htmlMinifier from 'html-minifier' import htmlMinifier from 'html-minifier'
@ -6,24 +5,11 @@ import htmlMinifier from 'html-minifier'
import Generator from '../src/generator' import Generator from '../src/generator'
import { createNuxt, hookCalls } from './__utils__' import { createNuxt, hookCalls } from './__utils__'
jest.mock('path')
jest.mock('fs-extra') jest.mock('fs-extra')
jest.mock('html-minifier') jest.mock('html-minifier')
jest.mock('@nuxt/utils') jest.mock('@nuxt/utils')
describe('generator: generate route', () => { describe('generator: generate route', () => {
const sep = path.sep
beforeAll(() => {
path.sep = '[sep]'
path.join.mockImplementation((...args) => `join(${args.join(', ')})`)
path.dirname.mockImplementation((...args) => `dirname(${args.join(', ')})`)
})
afterAll(() => {
path.sep = sep
})
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks() jest.clearAllMocks()
}) })
@ -34,7 +20,6 @@ describe('generator: generate route', () => {
nuxt.options.generate.minify = undefined nuxt.options.generate.minify = undefined
nuxt.options.generate.subFolders = false nuxt.options.generate.subFolders = false
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
const route = '/foo/' const route = '/foo/'
const payload = {} const payload = {}
@ -44,26 +29,38 @@ describe('generator: generate route', () => {
expect(nuxt.server.renderRoute).toBeCalledTimes(1) expect(nuxt.server.renderRoute).toBeCalledTimes(1)
expect(nuxt.server.renderRoute).toBeCalledWith(route, { payload }) expect(nuxt.server.renderRoute).toBeCalledWith(route, { payload })
expect(path.join).toBeCalledTimes(2)
expect(path.join).nthCalledWith(1, '[sep]', '/foo.html')
expect(path.join).nthCalledWith(2, generator.distPath, 'join([sep], /foo.html)')
expect(hookCalls(nuxt, 'generate:page')[0][0]).toMatchObject({ const genernatePageHookCall = hookCalls(nuxt, 'generate:page')[0][0]
expect(genernatePageHookCall).toMatchObject({
route, route,
html: 'rendered html', html: 'rendered html'
path: `join(${generator.distPath}, join([sep], /foo.html))`
}) })
expect(genernatePageHookCall.path).toBePath(
'/var/nuxt/generate/foo.html',
'C:\\nuxt\\generate\\foo.html'
)
expect(hookCalls(nuxt, 'generate:routeCreated')[0][0]).toMatchObject({ const genernateRouteCreatedHookCall = hookCalls(nuxt, 'generate:routeCreated')[0][0]
expect(genernateRouteCreatedHookCall).toMatchObject({
route, route,
errors: [], errors: []
path: `join(${generator.distPath}, join([sep], /foo.html))`
}) })
expect(genernateRouteCreatedHookCall.path).toBePath(
'/var/nuxt/generate/foo.html',
'C:\\nuxt\\generate\\foo.html'
)
expect(fsExtra.mkdirp).toBeCalledTimes(1) expect(fsExtra.mkdirp).toBeCalledTimes(1)
expect(fsExtra.mkdirp).toBeCalledWith(`dirname(join(${generator.distPath}, join([sep], /foo.html)))`) expect(fsExtra.mkdirp.mock.calls[0][0]).toBePath(
'/var/nuxt/generate',
'C:\\nuxt\\generate'
)
expect(fsExtra.writeFile).toBeCalledTimes(1) expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile).toBeCalledWith(`join(${generator.distPath}, join([sep], /foo.html))`, 'rendered html', 'utf8') expect(fsExtra.writeFile).toBeCalledWith(expect.any(String), 'rendered html', 'utf8')
expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/foo.html',
'C:\\nuxt\\generate\\foo.html'
)
expect(returned).toEqual(true) expect(returned).toEqual(true)
}) })
@ -158,7 +155,11 @@ describe('generator: generate route', () => {
expect(htmlMinifier.minify).toBeCalledTimes(1) expect(htmlMinifier.minify).toBeCalledTimes(1)
expect(htmlMinifier.minify).toBeCalledWith('rendered html', { value: 'test-minify' }) expect(htmlMinifier.minify).toBeCalledWith('rendered html', { value: 'test-minify' })
expect(fsExtra.writeFile).toBeCalledTimes(1) expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile).toBeCalledWith(`join(${generator.distPath}, join([sep], /foo.html))`, 'minified rendered html', 'utf8') expect(fsExtra.writeFile).toBeCalledWith(expect.any(String), 'minified rendered html', 'utf8')
expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/foo.html',
'C:\\nuxt\\generate\\foo.html'
)
expect(returned).toEqual(true) expect(returned).toEqual(true)
}) })
@ -191,17 +192,17 @@ describe('generator: generate route', () => {
nuxt.options.build.html = { minify: false } nuxt.options.build.html = { minify: false }
nuxt.options.generate.subFolders = true nuxt.options.generate.subFolders = true
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
const route = '/foo' const route = '/foo'
const returned = await generator.generateRoute({ route }) const returned = await generator.generateRoute({ route })
expect(path.join).toBeCalledTimes(2)
expect(path.join).nthCalledWith(1, route, '[sep]', 'index.html')
expect(path.join).nthCalledWith(2, generator.distPath, 'join(/foo, [sep], index.html)')
expect(fsExtra.writeFile).toBeCalledTimes(1) expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile).toBeCalledWith(`join(${generator.distPath}, join(/foo, [sep], index.html))`, 'rendered html', 'utf8') expect(fsExtra.writeFile).toBeCalledWith(expect.any(String), 'rendered html', 'utf8')
expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/foo/index.html',
'C:\\nuxt\\generate\\foo\\index.html'
)
expect(returned).toEqual(true) expect(returned).toEqual(true)
}) })
@ -210,18 +211,17 @@ describe('generator: generate route', () => {
nuxt.options.build.html = { minify: false } nuxt.options.build.html = { minify: false }
nuxt.options.generate.subFolders = true nuxt.options.generate.subFolders = true
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
path.join.mockReturnValueOnce('/404/index.html')
const route = '/404' const route = '/404'
const returned = await generator.generateRoute({ route }) const returned = await generator.generateRoute({ route })
expect(path.join).toBeCalledTimes(2)
expect(path.join).nthCalledWith(1, route, '[sep]', 'index.html')
expect(path.join).nthCalledWith(2, generator.distPath, '/404.html')
expect(fsExtra.writeFile).toBeCalledTimes(1) expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile).toBeCalledWith(`join(${generator.distPath}, /404.html)`, 'rendered html', 'utf8') expect(fsExtra.writeFile).toBeCalledWith(expect.any(String), 'rendered html', 'utf8')
expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/404.html',
'C:\\nuxt\\generate\\404.html'
)
expect(returned).toEqual(true) expect(returned).toEqual(true)
}) })
@ -229,17 +229,17 @@ describe('generator: generate route', () => {
const nuxt = createNuxt() const nuxt = createNuxt()
nuxt.options.build.html = { minify: false } nuxt.options.build.html = { minify: false }
const generator = new Generator(nuxt) const generator = new Generator(nuxt)
path.join.mockClear()
const route = '' const route = ''
const returned = await generator.generateRoute({ route }) const returned = await generator.generateRoute({ route })
expect(path.join).toBeCalledTimes(2)
expect(path.join).nthCalledWith(1, '[sep]', 'index.html')
expect(path.join).nthCalledWith(2, generator.distPath, 'join([sep], index.html)')
expect(fsExtra.writeFile).toBeCalledTimes(1) expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile).toBeCalledWith(`join(${generator.distPath}, join([sep], index.html))`, 'rendered html', 'utf8') expect(fsExtra.writeFile).toBeCalledWith(expect.any(String), 'rendered html', 'utf8')
expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/index.html',
'C:\\nuxt\\generate\\index.html'
)
expect(returned).toEqual(true) expect(returned).toEqual(true)
}) })
}) })

View File

@ -1,6 +1,4 @@
export default { export default {
build: true, build: true,
rollup: { externals: ['jsdom']
externals: ['jsdom']
}
} }

View File

@ -8,11 +8,9 @@
"dist" "dist"
], ],
"dependencies": { "dependencies": {
"@nuxt/config": "2.14.12",
"@nuxt/utils": "2.14.12", "@nuxt/utils": "2.14.12",
"@nuxt/vue-renderer": "2.14.12", "@nuxt/vue-renderer": "2.14.12",
"@nuxtjs/youch": "^4.2.3", "@nuxtjs/youch": "^4.2.3",
"chalk": "^4.1.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"connect": "^3.7.0", "connect": "^3.7.0",
"consola": "^2.15.0", "consola": "^2.15.0",

View File

@ -4,8 +4,9 @@ import launchMiddleware from 'launch-editor-middleware'
import serveStatic from 'serve-static' import serveStatic from 'serve-static'
import servePlaceholder from 'serve-placeholder' import servePlaceholder from 'serve-placeholder'
import connect from 'connect' import connect from 'connect'
import compression from 'compression'
import { determineGlobals, isUrl, urlJoin } from '@nuxt/utils' import { determineGlobals, isUrl, urlJoin } from '@nuxt/utils'
import { VueRenderer } from '@nuxt/vue-renderer'
import ServerContext from './context' import ServerContext from './context'
import renderAndGetWindow from './jsdom' import renderAndGetWindow from './jsdom'
import nuxtMiddleware from './middleware/nuxt' import nuxtMiddleware from './middleware/nuxt'
@ -53,8 +54,6 @@ export default class Server {
await this.nuxt.callHook('render:before', this, this.options.render) await this.nuxt.callHook('render:before', this, this.options.render)
// Initialize vue-renderer // Initialize vue-renderer
const { VueRenderer } = await import('@nuxt/vue-renderer')
this.serverContext = new ServerContext(this) this.serverContext = new ServerContext(this)
this.renderer = new VueRenderer(this.serverContext) this.renderer = new VueRenderer(this.serverContext)
await this.renderer.ready() await this.renderer.ready()
@ -77,7 +76,6 @@ export default class Server {
const { compressor } = this.options.render const { compressor } = this.options.render
if (typeof compressor === 'object') { if (typeof compressor === 'object') {
// If only setting for `compression` are provided, require the module and insert // If only setting for `compression` are provided, require the module and insert
const compression = this.nuxt.resolver.requireModule('compression')
this.useMiddleware(compression(compressor)) this.useMiddleware(compression(compressor))
} else if (compressor) { } else if (compressor) {
// Else, require own compression middleware if compressor is actually truthy // Else, require own compression middleware if compressor is actually truthy

View File

@ -1,4 +1,5 @@
import path from 'path' import path from 'path'
import compression from 'compression'
import connect from 'connect' import connect from 'connect'
import consola from 'consola' import consola from 'consola'
import serveStatic from 'serve-static' import serveStatic from 'serve-static'
@ -15,6 +16,7 @@ import nuxtMiddleware from '../src/middleware/nuxt'
import errorMiddleware from '../src/middleware/error' import errorMiddleware from '../src/middleware/error'
import createTimingMiddleware from '../src/middleware/timing' import createTimingMiddleware from '../src/middleware/timing'
jest.mock('compression')
jest.mock('connect') jest.mock('connect')
jest.mock('serve-static') jest.mock('serve-static')
jest.mock('serve-placeholder') jest.mock('serve-placeholder')
@ -229,12 +231,11 @@ describe('server: server', () => {
server.useMiddleware.mockClear() server.useMiddleware.mockClear()
nuxt.options.render.compressor = { id: 'test-render-compressor' } nuxt.options.render.compressor = { id: 'test-render-compressor' }
nuxt.resolver.requireModule.mockImplementationOnce(name => jest.fn(options => ({ compression.mockImplementationOnce(options => ({
name, name: 'compression',
...options ...options
}))) }))
await server.setupMiddleware() await server.setupMiddleware()
expect(nuxt.resolver.requireModule).nthCalledWith(1, 'compression')
expect(server.useMiddleware).nthCalledWith(1, { expect(server.useMiddleware).nthCalledWith(1, {
id: 'test-render-compressor', id: 'test-render-compressor',
name: 'compression' name: 'compression'

View File

@ -10,8 +10,10 @@
"dependencies": { "dependencies": {
"@nuxt/ufo": "^0.5.2", "@nuxt/ufo": "^0.5.2",
"consola": "^2.15.0", "consola": "^2.15.0",
"create-require": "^1.1.1",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"hash-sum": "^2.0.0", "hash-sum": "^2.0.0",
"lodash": "^4.17.20",
"proper-lockfile": "^4.1.1", "proper-lockfile": "^4.1.1",
"semver": "^7.3.4", "semver": "^7.3.4",
"serialize-javascript": "^5.0.1", "serialize-javascript": "^5.0.1",

View File

@ -1,4 +1,7 @@
import { join } from 'path' import { join } from 'path'
import createRequire from 'create-require'
const _require = createRequire()
export function isHMRCompatible (id) { export function isHMRCompatible (id) {
return !/[/\\]mongoose[/\\/]/.test(id) return !/[/\\]mongoose[/\\/]/.test(id)
@ -16,7 +19,7 @@ export function clearRequireCache (id) {
const entry = getRequireCacheItem(id) const entry = getRequireCacheItem(id)
if (!entry) { if (!entry) {
delete require.cache[id] delete _require.cache[id]
return return
} }
@ -25,7 +28,7 @@ export function clearRequireCache (id) {
} }
// Needs to be cleared before children, to protect against circular deps (#7966) // Needs to be cleared before children, to protect against circular deps (#7966)
delete require.cache[id] delete _require.cache[id]
for (const child of entry.children) { for (const child of entry.children) {
clearRequireCache(child.id) clearRequireCache(child.id)
@ -55,18 +58,34 @@ export function scanRequireTree (id, files = new Set()) {
export function getRequireCacheItem (id) { export function getRequireCacheItem (id) {
try { try {
return require.cache[id] return _require.cache[id]
} catch (e) { } catch (e) {
} }
} }
export function tryRequire (id) { export function resolveModule (id, paths) {
try { if (typeof paths === 'string') {
return require(id) paths = [paths]
} catch (e) {
} }
return _require.resolve(id, [
process.cwd(),
...(paths || []),
...(global.__NUXT_PATHS__ || [])
])
} }
export function getPKG (id) { export function requireModule (id, paths) {
return tryRequire(join(id, 'package.json')) return _require(resolveModule(id, paths))
}
export function tryRequire (id, paths) {
try { return requireModule(id, paths) } catch (e) { }
}
export function tryResolve (id, paths) {
try { return resolveModule(id, paths) } catch (e) { }
}
export function getPKG (id, paths) {
return tryRequire(join(id, 'package.json'), paths)
} }

View File

@ -1,4 +1,5 @@
import UAParser from 'ua-parser-js' import UAParser from 'ua-parser-js'
import semver from 'semver'
export const ModernBrowsers = { export const ModernBrowsers = {
Edge: '16', Edge: '16',
@ -14,7 +15,6 @@ export const ModernBrowsers = {
'Mobile Safari': '10.3' 'Mobile Safari': '10.3'
} }
let semver
let __modernBrowsers let __modernBrowsers
const getModernBrowsers = () => { const getModernBrowsers = () => {
@ -34,9 +34,6 @@ export const isModernBrowser = (ua) => {
if (!ua) { if (!ua) {
return false return false
} }
if (!semver) {
semver = require('semver')
}
const { browser } = UAParser(ua) const { browser } = UAParser(ua)
const browserVersion = semver.coerce(browser.version) const browserVersion = semver.coerce(browser.version)
if (!browserVersion) { if (!browserVersion) {

View File

@ -1,6 +1,6 @@
import path from 'path' import path from 'path'
import consola from 'consola' import consola from 'consola'
import escapeRegExp from 'lodash/escapeRegExp' import { escapeRegExp } from 'lodash'
export const startsWithAlias = aliasArray => str => aliasArray.some(c => str.startsWith(c)) export const startsWithAlias = aliasArray => str => aliasArray.some(c => str.startsWith(c))
@ -105,5 +105,5 @@ export function isIndexFileAndFolder (pluginFiles) {
} }
export const getMainModule = () => { export const getMainModule = () => {
return require.main || (module && module.main) || module return (require && require.main) || (module && module.main) || module
} }

View File

@ -1,5 +1,5 @@
import path from 'path' import path from 'path'
import get from 'lodash/get' import { get } from 'lodash'
import consola from 'consola' import consola from 'consola'
import { normalizeURL, withTrailingSlash, withoutTrailingSlash } from '@nuxt/ufo' import { normalizeURL, withTrailingSlash, withoutTrailingSlash } from '@nuxt/ufo'
import { r } from './resolve' import { r } from './resolve'

View File

@ -1,3 +1,16 @@
export default { export default {
build: true build: true,
ignoreUnused: [
// used in vue-app
'@nuxt/ufo',
'node-fetch',
'unfetch',
'vue',
'vue-client-only',
'vue-meta',
'vue-no-ssr',
'vue-router',
'vue-template-compiler',
'vuex'
]
} }

View File

@ -13,6 +13,7 @@
"@nuxt/utils": "2.14.12", "@nuxt/utils": "2.14.12",
"consola": "^2.15.0", "consola": "^2.15.0",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"lodash": "^4.17.20",
"lru-cache": "^5.1.1", "lru-cache": "^5.1.1",
"vue": "^2.6.12", "vue": "^2.6.12",
"vue-meta": "^2.4.0", "vue-meta": "^2.4.0",

View File

@ -1,7 +1,7 @@
import path from 'path' import path from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import consola from 'consola' import consola from 'consola'
import template from 'lodash/template' import { template } from 'lodash'
import { TARGETS, isModernRequest, waitFor } from '@nuxt/utils' import { TARGETS, isModernRequest, waitFor } from '@nuxt/utils'
import { normalizeURL } from '@nuxt/ufo' import { normalizeURL } from '@nuxt/ufo'

View File

@ -1,5 +1,5 @@
import { extname } from 'path' import { extname } from 'path'
import cloneDeep from 'lodash/cloneDeep' import { cloneDeep } from 'lodash'
import VueMeta from 'vue-meta' import VueMeta from 'vue-meta'
import { createRenderer } from 'vue-server-renderer' import { createRenderer } from 'vue-server-renderer'
import LRU from 'lru-cache' import LRU from 'lru-cache'

View File

@ -1,3 +1,18 @@
export default { export default {
build: true build: true,
ignoreUnused: [
'@nuxt/babel-preset-app',
'babel-loader',
'cache-loader',
'caniuse-lite',
'css-loader',
'cssnano',
'eventsource-polyfill',
'file-loader',
'postcss-loader',
'postcss-preset-env',
'postcss-url',
'style-resources-loader',
'url-loader'
]
} }

View File

@ -8,16 +8,13 @@
"dist" "dist"
], ],
"dependencies": { "dependencies": {
"@babel/core": "^7.12.10",
"@nuxt/babel-preset-app": "2.14.12", "@nuxt/babel-preset-app": "2.14.12",
"@nuxt/friendly-errors-webpack-plugin": "^2.5.0", "@nuxt/friendly-errors-webpack-plugin": "^2.5.0",
"@nuxt/utils": "2.14.12", "@nuxt/utils": "2.14.12",
"babel-loader": "^8.2.2", "babel-loader": "^8.2.2",
"cache-loader": "^4.1.0", "cache-loader": "^4.1.0",
"caniuse-lite": "^1.0.30001170", "caniuse-lite": "^1.0.30001168",
"chalk": "^4.1.0",
"consola": "^2.15.0", "consola": "^2.15.0",
"create-require": "^1.1.1",
"css-loader": "^4.3.0", "css-loader": "^4.3.0",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"eventsource-polyfill": "^0.9.6", "eventsource-polyfill": "^0.9.6",
@ -27,9 +24,11 @@
"hard-source-webpack-plugin": "^0.13.1", "hard-source-webpack-plugin": "^0.13.1",
"hash-sum": "^2.0.0", "hash-sum": "^2.0.0",
"html-webpack-plugin": "^4.5.0", "html-webpack-plugin": "^4.5.0",
"lodash": "^4.17.20",
"memory-fs": "^0.5.0", "memory-fs": "^0.5.0",
"optimize-css-assets-webpack-plugin": "^5.0.4", "optimize-css-assets-webpack-plugin": "^5.0.4",
"pify": "^5.0.0", "pify": "^5.0.0",
"pnp-webpack-plugin": "^1.6.4",
"postcss": "^7.0.32", "postcss": "^7.0.32",
"postcss-import": "^12.0.1", "postcss-import": "^12.0.1",
"postcss-import-resolver": "^2.0.0", "postcss-import-resolver": "^2.0.0",

View File

@ -6,7 +6,7 @@ import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware' import webpackHotMiddleware from 'webpack-hot-middleware'
import consola from 'consola' import consola from 'consola'
import { TARGETS, parallel, sequence, wrapArray, isModernRequest } from '@nuxt/utils' import { TARGETS, parallel, sequence, tryResolve, wrapArray, isModernRequest } from '@nuxt/utils'
import AsyncMFS from './utils/async-mfs' import AsyncMFS from './utils/async-mfs'
import * as WebpackConfigs from './config' import * as WebpackConfigs from './config'
@ -92,7 +92,7 @@ export class WebpackBundler {
// Warm up perfLoader before build // Warm up perfLoader before build
if (options.build.parallel) { if (options.build.parallel) {
consola.info('Warming up worker pools') consola.info('Warming up worker pools')
PerfLoader.warmupAll({ dev: options.dev }) PerfLoader.warmupAll({ dev: options.dev, resolveModule: id => tryResolve(id, __filename) || id })
consola.success('Worker pools ready') consola.success('Worker pools ready')
} }

View File

@ -1,19 +1,18 @@
import path from 'path' import path from 'path'
import consola from 'consola' import consola from 'consola'
import TimeFixPlugin from 'time-fix-plugin' import TimeFixPlugin from 'time-fix-plugin'
import cloneDeep from 'lodash/cloneDeep' import { escapeRegExp, cloneDeep } from 'lodash'
import escapeRegExp from 'lodash/escapeRegExp'
import VueLoader from 'vue-loader' import VueLoader from 'vue-loader'
import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin' import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin'
import * as PnpWebpackPlugin from 'pnp-webpack-plugin'
import HardSourcePlugin from 'hard-source-webpack-plugin' import HardSourcePlugin from 'hard-source-webpack-plugin'
import TerserWebpackPlugin from 'terser-webpack-plugin' import TerserWebpackPlugin from 'terser-webpack-plugin'
import WebpackBar from 'webpackbar' import WebpackBar from 'webpackbar'
import env from 'std-env' import env from 'std-env'
import semver from 'semver' import semver from 'semver'
import { TARGETS, isUrl, urlJoin, getPKG } from '@nuxt/utils' import { TARGETS, isUrl, urlJoin, getPKG, tryResolve, requireModule } from '@nuxt/utils'
import createRequire from 'create-require'
import PerfLoader from '../utils/perf-loader' import PerfLoader from '../utils/perf-loader'
import StyleLoader from '../utils/style-loader' import StyleLoader from '../utils/style-loader'
import WarningIgnorePlugin from '../plugins/warning-ignore' import WarningIgnorePlugin from '../plugins/warning-ignore'
@ -23,6 +22,7 @@ export default class WebpackBaseConfig {
constructor (builder) { constructor (builder) {
this.builder = builder this.builder = builder
this.buildContext = builder.buildContext this.buildContext = builder.buildContext
this.resolveModule = id => tryResolve(id) || id
} }
get colors () { get colors () {
@ -121,7 +121,7 @@ export default class WebpackBaseConfig {
let corejsVersion = corejs let corejsVersion = corejs
if (corejsVersion === 'auto') { if (corejsVersion === 'auto') {
try { try {
corejsVersion = Number.parseInt(createRequire(rootDir)('core-js/package.json').version.split('.')[0]) corejsVersion = Number.parseInt(requireModule('core-js/package.json', rootDir).version.split('.')[0])
} catch (_err) { } catch (_err) {
corejsVersion = 2 corejsVersion = 2
} }
@ -134,7 +134,7 @@ export default class WebpackBaseConfig {
corejsVersion = 2 corejsVersion = 2
} }
const defaultPreset = [require.resolve('@nuxt/babel-preset-app'), { const defaultPreset = [this.resolveModule('@nuxt/babel-preset-app'), {
corejs: { corejs: {
version: corejsVersion version: corejsVersion
} }
@ -229,12 +229,20 @@ export default class WebpackBaseConfig {
resolve: { resolve: {
extensions: ['.wasm', '.mjs', '.js', '.json', '.vue', '.jsx'], extensions: ['.wasm', '.mjs', '.js', '.json', '.vue', '.jsx'],
alias: this.alias(), alias: this.alias(),
modules: webpackModulesDir modules: webpackModulesDir,
plugins: [
PnpWebpackPlugin,
PnpWebpackPlugin.moduleLoader(this.buildContext.options.rootDir),
PnpWebpackPlugin.moduleLoader(__dirname)
]
}, },
resolveLoader: { resolveLoader: {
modules: [ modules: [
path.resolve(__dirname, '../node_modules'), path.resolve(__dirname, '../node_modules'),
...webpackModulesDir ...webpackModulesDir
],
plugins: [
PnpWebpackPlugin.moduleLoader(module)
] ]
} }
} }
@ -271,26 +279,26 @@ export default class WebpackBaseConfig {
alias () { alias () {
return { return {
...this.buildContext.options.alias, ...this.buildContext.options.alias,
'vue-meta': require.resolve(`vue-meta${this.isServer ? '' : '/dist/vue-meta.esm.browser.js'}`) 'vue-meta': this.resolveModule(`vue-meta${this.isServer ? '' : '/dist/vue-meta.esm.browser.js'}`)
} }
} }
rules () { rules () {
const perfLoader = new PerfLoader(this.name, this.buildContext) const perfLoader = new PerfLoader(this.name, this.buildContext, { resolveModule: this.resolveModule })
const styleLoader = new StyleLoader( const styleLoader = new StyleLoader(
this.buildContext, this.buildContext,
{ isServer: this.isServer, perfLoader } { isServer: this.isServer, perfLoader, resolveModule: this.resolveModule }
) )
const babelLoader = { const babelLoader = {
loader: require.resolve('babel-loader'), loader: this.resolveModule('babel-loader'),
options: this.getBabelOptions() options: this.getBabelOptions()
} }
return [ return [
{ {
test: /\.vue$/i, test: /\.vue$/i,
loader: 'vue-loader', loader: this.resolveModule('vue-loader'),
options: this.loaders.vue options: this.loaders.vue
}, },
{ {
@ -299,15 +307,15 @@ export default class WebpackBaseConfig {
{ {
resourceQuery: /^\?vue/i, resourceQuery: /^\?vue/i,
use: [{ use: [{
loader: 'pug-plain-loader', loader: this.resolveModule('pug-plain-loader'),
options: this.loaders.pugPlain options: this.loaders.pugPlain
}] }]
}, },
{ {
use: [ use: [
'raw-loader', this.resolveModule('raw-loader'),
{ {
loader: 'pug-plain-loader', loader: this.resolveModule('pug-plain-loader'),
options: this.loaders.pugPlain options: this.loaders.pugPlain
} }
] ]
@ -340,35 +348,35 @@ export default class WebpackBaseConfig {
{ {
test: /\.less$/i, test: /\.less$/i,
oneOf: styleLoader.apply('less', { oneOf: styleLoader.apply('less', {
loader: 'less-loader', loader: this.resolveModule('less-loader'),
options: this.loaders.less options: this.loaders.less
}) })
}, },
{ {
test: /\.sass$/i, test: /\.sass$/i,
oneOf: styleLoader.apply('sass', { oneOf: styleLoader.apply('sass', {
loader: 'sass-loader', loader: this.resolveModule('sass-loader'),
options: this.loaders.sass options: this.loaders.sass
}) })
}, },
{ {
test: /\.scss$/i, test: /\.scss$/i,
oneOf: styleLoader.apply('scss', { oneOf: styleLoader.apply('scss', {
loader: 'sass-loader', loader: this.resolveModule('sass-loader'),
options: this.loaders.scss options: this.loaders.scss
}) })
}, },
{ {
test: /\.styl(us)?$/i, test: /\.styl(us)?$/i,
oneOf: styleLoader.apply('stylus', { oneOf: styleLoader.apply('stylus', {
loader: 'stylus-loader', loader: this.resolveModule('stylus-loader'),
options: this.loaders.stylus options: this.loaders.stylus
}) })
}, },
{ {
test: /\.(png|jpe?g|gif|svg|webp|avif)$/i, test: /\.(png|jpe?g|gif|svg|webp|avif)$/i,
use: [{ use: [{
loader: 'url-loader', loader: this.resolveModule('url-loader'),
options: Object.assign( options: Object.assign(
this.loaders.imgUrl, this.loaders.imgUrl,
{ name: this.getFileName('img') } { name: this.getFileName('img') }
@ -378,7 +386,7 @@ export default class WebpackBaseConfig {
{ {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
use: [{ use: [{
loader: 'url-loader', loader: this.resolveModule('url-loader'),
options: Object.assign( options: Object.assign(
this.loaders.fontUrl, this.loaders.fontUrl,
{ name: this.getFileName('font') } { name: this.getFileName('font') }
@ -388,7 +396,7 @@ export default class WebpackBaseConfig {
{ {
test: /\.(webm|mp4|ogv)$/i, test: /\.(webm|mp4|ogv)$/i,
use: [{ use: [{
loader: 'file-loader', loader: this.resolveModule('file-loader'),
options: Object.assign( options: Object.assign(
this.loaders.file, this.loaders.file,
{ name: this.getFileName('video') } { name: this.getFileName('video') }

View File

@ -199,9 +199,9 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
if (this.dev) { if (this.dev) {
config.entry.app.unshift( config.entry.app.unshift(
// https://github.com/webpack-contrib/webpack-hot-middleware/issues/53#issuecomment-162823945 // https://github.com/webpack-contrib/webpack-hot-middleware/issues/53#issuecomment-162823945
'eventsource-polyfill', this.resolveModule('eventsource-polyfill'),
// https://github.com/glenjamin/webpack-hot-middleware#config // https://github.com/glenjamin/webpack-hot-middleware#config
`webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}` `${this.resolveModule('webpack-hot-middleware/client')}?${hotMiddlewareClientOptionsStr}`
) )
} }

View File

@ -4,7 +4,7 @@
*/ */
import hash from 'hash-sum' import hash from 'hash-sum'
import uniq from 'lodash/uniq' import { uniq } from 'lodash'
import { isJS, isCSS } from './util' import { isJS, isCSS } from './util'

View File

@ -6,10 +6,11 @@ import { warmup } from 'thread-loader'
// https://github.com/webpack-contrib/cache-loader // https://github.com/webpack-contrib/cache-loader
export default class PerfLoader { export default class PerfLoader {
constructor (name, buildContext) { constructor (name, buildContext, { resolveModule }) {
this.name = name this.name = name
this.buildContext = buildContext this.buildContext = buildContext
this.workerPools = PerfLoader.defaultPools({ dev: buildContext.options.dev }) this.workerPools = PerfLoader.defaultPools({ dev: buildContext.options.dev })
this.resolveModule = resolveModule
return new Proxy(this, { return new Proxy(this, {
get (target, name) { get (target, name) {
return target[name] ? target[name] : target.use.bind(target, name) return target[name] ? target[name] : target.use.bind(target, name)
@ -25,13 +26,13 @@ export default class PerfLoader {
} }
} }
static warmupAll ({ dev }) { static warmupAll ({ dev, resolveModule }) {
const pools = PerfLoader.defaultPools({ dev }) const pools = PerfLoader.defaultPools({ dev })
PerfLoader.warmup(pools.js, [ PerfLoader.warmup(pools.js, [
require.resolve('babel-loader'), resolveModule('babel-loader'),
require.resolve('@babel/preset-env') resolveModule('@babel/preset-env')
]) ])
PerfLoader.warmup(pools.css, ['css-loader']) PerfLoader.warmup(pools.css, [resolveModule('css-loader')])
} }
static warmup (...args) { static warmup (...args) {
@ -43,7 +44,7 @@ export default class PerfLoader {
if (this.buildContext.buildOptions.cache) { if (this.buildContext.buildOptions.cache) {
loaders.push({ loaders.push({
loader: 'cache-loader', loader: this.resolveModule('cache-loader'),
options: { options: {
cacheDirectory: path.resolve(`node_modules/.cache/cache-loader/${this.name}`) cacheDirectory: path.resolve(`node_modules/.cache/cache-loader/${this.name}`)
} }
@ -54,7 +55,7 @@ export default class PerfLoader {
const pool = this.workerPools[poolName] const pool = this.workerPools[poolName]
if (pool) { if (pool) {
loaders.push({ loaders.push({
loader: 'thread-loader', loader: this.resolveModule('thread-loader'),
options: pool options: pool
}) })
} }

View File

@ -1,9 +1,7 @@
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import consola from 'consola' import consola from 'consola'
import defaults from 'lodash/defaults' import { defaults, merge, cloneDeep } from 'lodash'
import merge from 'lodash/merge'
import cloneDeep from 'lodash/cloneDeep'
import createResolver from 'postcss-import-resolver' import createResolver from 'postcss-import-resolver'
import { isPureObject } from '@nuxt/utils' import { isPureObject } from '@nuxt/utils'

View File

@ -6,10 +6,11 @@ import { wrapArray } from '@nuxt/utils'
import PostcssConfig from './postcss' import PostcssConfig from './postcss'
export default class StyleLoader { export default class StyleLoader {
constructor (buildContext, { isServer, perfLoader }) { constructor (buildContext, { isServer, perfLoader, resolveModule }) {
this.buildContext = buildContext this.buildContext = buildContext
this.isServer = isServer this.isServer = isServer
this.perfLoader = perfLoader this.perfLoader = perfLoader
this.resolveModule = resolveModule
if (buildContext.options.build.postcss) { if (buildContext.options.build.postcss) {
this.postcssConfig = new PostcssConfig(buildContext) this.postcssConfig = new PostcssConfig(buildContext)
@ -40,7 +41,7 @@ export default class StyleLoader {
const patterns = wrapArray(extResource).map(p => path.resolve(rootDir, p)) const patterns = wrapArray(extResource).map(p => path.resolve(rootDir, p))
return { return {
loader: 'style-resources-loader', loader: this.resolveModule('style-resources-loader'),
options: Object.assign( options: Object.assign(
{ patterns }, { patterns },
styleResources.options || {} styleResources.options || {}
@ -62,13 +63,13 @@ export default class StyleLoader {
} }
return { return {
loader: 'postcss-loader', loader: this.resolveModule('postcss-loader'),
options: Object.assign({ sourceMap: this.buildContext.buildOptions.cssSourceMap }, config) options: Object.assign({ sourceMap: this.buildContext.buildOptions.cssSourceMap }, config)
} }
} }
css (options) { css (options) {
const cssLoader = { loader: 'css-loader', options } const cssLoader = { loader: this.resolveModule('css-loader'), options }
if (this.exportOnlyLocals) { if (this.exportOnlyLocals) {
options.modules = { options.modules = {
@ -102,7 +103,7 @@ export default class StyleLoader {
styleLoader () { styleLoader () {
return this.extract() || { return this.extract() || {
loader: 'vue-style-loader', loader: this.resolveModule('vue-style-loader'),
options: this.buildContext.buildOptions.loaders.vueStyle options: this.buildContext.buildOptions.loaders.vueStyle
} }
} }

View File

@ -1,8 +1,6 @@
import consola from 'consola' import consola from 'consola'
import execa from 'execa' import execa from 'execa'
import groupBy from 'lodash/groupBy' import { uniq, sortBy, groupBy } from 'lodash'
import sortBy from 'lodash/sortBy'
import uniq from 'lodash/uniq'
import { writeFile } from 'fs-extra' import { writeFile } from 'fs-extra'
const types = { const types = {

View File

@ -1,4 +1,3 @@
#!/usr/bin/env node -r esm
import path from 'path' import path from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import consola from 'consola' import consola from 'consola'
@ -11,7 +10,7 @@ const useCjs = [
const stub = { const stub = {
es: 'export * from \'../src/index\'', es: 'export * from \'../src/index\'',
cjs: `const _require = typeof jest === 'undefined' ? require('esm')(module) : require cjs: `const _require = typeof jest === 'undefined' ? require('jiti')(__dirname) : require
global.__NUXT_DEV__ = true global.__NUXT_DEV__ = true
module.exports = _require('../src/index') module.exports = _require('../src/index')
` `

View File

@ -1,8 +1,11 @@
const path = require('path') import path from 'path'
const consola = require('consola') import consola from 'consola'
const execa = require('execa') import execa from 'execa'
const fs = require('fs-extra') import fs from 'fs-extra'
const glob = require('pify')(require('glob')) import _glob from 'glob'
import pify from 'pify'
const glob = pify(_glob) // TODO: use globby
async function main () { async function main () {
const packageDirs = await glob('+(packages|distributions)/*') const packageDirs = await glob('+(packages|distributions)/*')

View File

@ -1,5 +1,3 @@
#!/usr/bin/env node -r esm
import consola from 'consola' import consola from 'consola'
import Package from './package.js' import Package from './package.js'

View File

@ -9,6 +9,7 @@ import pify from 'pify'
import sortPackageJson from 'sort-package-json' import sortPackageJson from 'sort-package-json'
import rollupConfig from './rollup.config' import rollupConfig from './rollup.config'
import { builtins } from './builtins'
const DEFAULTS = { const DEFAULTS = {
rootDir: process.cwd(), rootDir: process.cwd(),
@ -185,11 +186,22 @@ export default class Package {
} }
async build (_watch = false) { async build (_watch = false) {
// Externals
const externals = [
// Dependencies that will be installed alongise with the nuxt package
...Object.keys(this.pkg.dependencies || {}),
// Builtin node modules
...builtins,
// Custom externals
...(this.options.externals || [])
]
// Prepare rollup config // Prepare rollup config
const config = { const config = {
rootDir: this.options.rootDir, rootDir: this.options.rootDir,
alias: {}, alias: {},
replace: {}, replace: {},
externals,
...this.options.rollup ...this.options.rollup
} }
@ -250,27 +262,30 @@ export default class Package {
try { try {
const bundle = await rollup(_rollupConfig) const bundle = await rollup(_rollupConfig)
await remove(_rollupConfig.output.dir) await remove(_rollupConfig.output.dir)
await bundle.write(_rollupConfig.output) const result = await bundle.write(_rollupConfig.output)
this.logger.success('Bundle built') this.logger.success('Bundle built')
await this.callHook('build:done', { bundle }) await this.callHook('build:done', { bundle })
// Analyze bundle imports against pkg // Analyze bundle imports against pkg
// if (this.pkg.dependencies) { const dependencies = Object.keys(this.pkg.dependencies || {})
// const dependencies = {} const imports = [].concat(...result.output.map(o => o.imports))
// for (const dep in this.pkg.dependencies) {
// dependencies[dep] = this.pkg.dependencies[dep] const missingDependencies = imports
// } .filter(i => !i.endsWith('.js')) // dynamic imports
// for (const imp of bundle.imports) { .filter(i => !dependencies.includes(i) && !externals.find(e => i.startsWith(e)))
// delete dependencies[imp] if (missingDependencies.length) {
// } throw new Error(`Missing dependencies in ${this.pkg.name}: ` + missingDependencies.join(', '))
// for (const dep in dependencies) { }
// this.logger.warn(`Unused dependency ${dep}@${dependencies[dep]}`) const ignoreUnused = this.options.ignoreUnused || []
// } const unusedDependencies = dependencies.filter(d =>
// } !imports.find(i => i.startsWith(d)) && !ignoreUnused.includes(d)
)
if (unusedDependencies.length) {
throw new Error(`Unused dependencies in ${this.pkg.name}: ` + unusedDependencies.join(', '))
}
} catch (err) { } catch (err) {
this.formatError(err) this.formatError(err)
this.logger.error(err)
throw err throw err
} }
} }
@ -282,7 +297,7 @@ export default class Package {
const { file, column, line } = error.loc const { file, column, line } = error.loc
loc = `${file}:${line}:${column}` loc = `${file}:${line}:${column}`
} }
error.message = `[${error.code}] ${error.message}\nat ${loc}` error.message = `[${error.code || ''}] ${error.message}\nat ${loc}`
return error return error
} }

View File

@ -4,11 +4,9 @@ import jsonPlugin from '@rollup/plugin-json'
import commonjsPlugin from '@rollup/plugin-commonjs' import commonjsPlugin from '@rollup/plugin-commonjs'
import replacePlugin from '@rollup/plugin-replace' import replacePlugin from '@rollup/plugin-replace'
import aliasPlugin from '@rollup/plugin-alias' import aliasPlugin from '@rollup/plugin-alias'
import nodeResolvePlugin from '@rollup/plugin-node-resolve' // import nodeResolvePlugin from '@rollup/plugin-node-resolve'
import licensePlugin from 'rollup-plugin-license' import licensePlugin from 'rollup-plugin-license'
import defaultsDeep from 'lodash/defaultsDeep' import { defaultsDeep } from 'lodash'
import { builtins } from './builtins'
export default function rollupConfig ({ export default function rollupConfig ({
rootDir = process.cwd(), rootDir = process.cwd(),
@ -17,12 +15,6 @@ export default function rollupConfig ({
replace = {}, replace = {},
alias = {}, alias = {},
externals = [], externals = [],
resolve = {
resolveOnly: [
/lodash/,
/^((?!node_modules).)*$/
]
},
...options ...options
}, pkg) { }, pkg) {
if (!pkg) { if (!pkg) {
@ -40,14 +32,7 @@ export default function rollupConfig ({
format: 'cjs', format: 'cjs',
preferConst: true preferConst: true
}, },
external: [ external: externals,
// Dependencies that will be installed alongise with the nuxt package
...Object.keys(pkg.dependencies || {}),
// Builtin node modules
...builtins,
// Explicit externals
...externals
],
plugins: [ plugins: [
aliasPlugin(alias), aliasPlugin(alias),
replacePlugin({ replacePlugin({
@ -58,7 +43,12 @@ export default function rollupConfig ({
...replace ...replace
} }
}), }),
nodeResolvePlugin(resolve), // nodeResolvePlugin({
// preferBuiltins: true,
// resolveOnly: [
// /lodash/
// ]
// }),
commonjsPlugin({ include: /node_modules/ }), commonjsPlugin({ include: /node_modules/ }),
jsonPlugin(), jsonPlugin(),
licensePlugin({ licensePlugin({

View File

@ -6,12 +6,13 @@ describe('webpack configuration', () => {
test('performance loader', () => { test('performance loader', () => {
const js = { name: 'js', poolTimeout: Infinity } const js = { name: 'js', poolTimeout: Infinity }
const css = { name: 'css', poolTimeout: Infinity } const css = { name: 'css', poolTimeout: Infinity }
const resolveModule = jest.fn(id => id)
PerfLoader.warmup = jest.fn() PerfLoader.warmup = jest.fn()
PerfLoader.warmupAll({ dev: true }) PerfLoader.warmupAll({ dev: true, resolveModule })
expect(PerfLoader.warmup).toHaveBeenCalledTimes(2) expect(PerfLoader.warmup).toHaveBeenCalledTimes(2)
expect(PerfLoader.warmup).toHaveBeenCalledWith(js, [ expect(PerfLoader.warmup).toHaveBeenCalledWith(js, [
require.resolve('babel-loader'), 'babel-loader',
require.resolve('@babel/preset-env') '@babel/preset-env'
]) ])
expect(PerfLoader.warmup).toHaveBeenCalledWith(css, ['css-loader']) expect(PerfLoader.warmup).toHaveBeenCalledWith(css, ['css-loader'])
@ -25,6 +26,9 @@ describe('webpack configuration', () => {
parallel: true, parallel: true,
cache: true cache: true
} }
},
{
resolveModule
} }
) )
expect(perfLoader.workerPools).toMatchObject({ js, css }) expect(perfLoader.workerPools).toMatchObject({ js, css })

View File

@ -1,5 +1,5 @@
import { resolve } from 'path' import { resolve } from 'path'
import defaultsDeep from 'lodash/defaultsDeep' import { defaultsDeep } from 'lodash'
import baseNuxtConfig from '../spa/nuxt.config' import baseNuxtConfig from '../spa/nuxt.config'
const config = { const config = {

View File

@ -1,5 +1,5 @@
import { resolve } from 'path' import { resolve } from 'path'
import defaultsDeep from 'lodash/defaultsDeep' import { defaultsDeep } from 'lodash'
import baseNuxtConfig from '../spa/nuxt.config' import baseNuxtConfig from '../spa/nuxt.config'
const config = { const config = {

View File

@ -8,7 +8,7 @@ import path from 'path'
import { execSync, execFileSync } from 'child_process' import { execSync, execFileSync } from 'child_process'
import isWsl from 'is-wsl' import isWsl from 'is-wsl'
import consola from 'consola' import consola from 'consola'
import uniq from 'lodash/uniq' import { uniq } from 'lodash'
const newLineRegex = /\r?\n/ const newLineRegex = /\r?\n/

View File

@ -21,3 +21,15 @@ function errorTrap (error) {
process.on('unhandledRejection', errorTrap) process.on('unhandledRejection', errorTrap)
process.on('uncaughtException', errorTrap) process.on('uncaughtException', errorTrap)
expect.extend({
toBePath (received, posixPath, winPath) {
const expectedPath = isWin ? winPath : posixPath
const pass = received === expectedPath
return {
pass,
message: () =>
`expected path ${received} to be ${expectedPath}`
}
}
})

View File

@ -3966,7 +3966,7 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, can
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001168.tgz#6fcd098c139d003b9bd484cbb9ca26cb89907f9a" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001168.tgz#6fcd098c139d003b9bd484cbb9ca26cb89907f9a"
integrity sha512-P2zmX7swIXKu+GMMR01TWa4csIKELTNnZKc+f1CjebmZJQtTAEXmpQSoKVJVVcvPGAA0TEYTOUp3VehavZSFPQ== integrity sha512-P2zmX7swIXKu+GMMR01TWa4csIKELTNnZKc+f1CjebmZJQtTAEXmpQSoKVJVVcvPGAA0TEYTOUp3VehavZSFPQ==
caniuse-lite@^1.0.30001170: caniuse-lite@^1.0.30001168:
version "1.0.30001170" version "1.0.30001170"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7"
integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA== integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA==
@ -4973,7 +4973,7 @@ debug@3.1.0:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0: debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
version "4.3.1" version "4.3.1"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
@ -5761,11 +5761,6 @@ eslint@^7.16.0:
text-table "^0.2.0" text-table "^0.2.0"
v8-compile-cache "^2.0.3" v8-compile-cache "^2.0.3"
esm@^3.2.25:
version "3.2.25"
resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
espree@^6.2.1: espree@^6.2.1:
version "6.2.1" version "6.2.1"
resolved "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" resolved "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a"
@ -8500,7 +8495,7 @@ lodash@4.17.19:
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
lodash@^4.15.0, lodash@^4.17.12, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@^4.2.1: lodash@^4.15.0, lodash@^4.17.12, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.4.2:
version "4.17.20" version "4.17.20"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
@ -10041,6 +10036,13 @@ pluralize@^8.0.0:
resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
pnp-webpack-plugin@^1.6.4:
version "1.6.4"
resolved "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149"
integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==
dependencies:
ts-pnp "^1.1.6"
posix-character-classes@^0.1.0: posix-character-classes@^0.1.0:
version "0.1.1" version "0.1.1"
resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
@ -12768,6 +12770,11 @@ ts-jest@26.x:
semver "7.x" semver "7.x"
yargs-parser "20.x" yargs-parser "20.x"
ts-pnp@^1.1.6:
version "1.2.0"
resolved "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==
tsconfig-paths@^3.9.0: tsconfig-paths@^3.9.0:
version "3.9.0" version "3.9.0"
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
@ -13052,11 +13059,6 @@ url-loader@^4.1.1:
mime-types "^2.1.27" mime-types "^2.1.27"
schema-utils "^3.0.0" schema-utils "^3.0.0"
url-polyfill@^1.1.12:
version "1.1.12"
resolved "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.12.tgz#6cdaa17f6b022841b3aec0bf8dbd87ac0cd33331"
integrity sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==
url@^0.11.0: url@^0.11.0:
version "0.11.0" version "0.11.0"
resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"