UNPKG

22.3 kBJavaScriptView Raw
1/*!
2 * @nuxt/core-edge v2.14.8-26735067.baf94d31 (c) 2016-2020
3
4 * - All the amazing contributors
5 * Released under the MIT License.
6 * Website: https://nuxtjs.org
7*/
8'use strict';
9
10Object.defineProperty(exports, '__esModule', { value: true });
11
12const path = require('path');
13const fs = require('fs');
14const hash = require('hash-sum');
15const consola = require('consola');
16const utilsEdge = require('@nuxt/utils-edge');
17const Hookable = require('hable');
18const configEdge = require('@nuxt/config-edge');
19const serverEdge = require('@nuxt/server-edge');
20const fs$1 = require('fs-extra');
21
22function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
23
24const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
25const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
26const hash__default = /*#__PURE__*/_interopDefaultLegacy(hash);
27const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola);
28const Hookable__default = /*#__PURE__*/_interopDefaultLegacy(Hookable);
29const fs__default$1 = /*#__PURE__*/_interopDefaultLegacy(fs$1);
30
31class ModuleContainer {
32 constructor (nuxt) {
33 this.nuxt = nuxt;
34 this.options = nuxt.options;
35 this.requiredModules = {};
36
37 // Self bind to allow destructre from container
38 for (const method of Object.getOwnPropertyNames(ModuleContainer.prototype)) {
39 if (typeof this[method] === 'function') {
40 this[method] = this[method].bind(this);
41 }
42 }
43 }
44
45 async ready () {
46 // Call before hook
47 await this.nuxt.callHook('modules:before', this, this.options.modules);
48
49 if (this.options.buildModules && !this.options._start) {
50 // Load every devModule in sequence
51 await utilsEdge.sequence(this.options.buildModules, this.addModule);
52 }
53
54 // Load every module in sequence
55 await utilsEdge.sequence(this.options.modules, this.addModule);
56
57 // Load ah-hoc modules last
58 await utilsEdge.sequence(this.options._modules, this.addModule);
59
60 // Call done hook
61 await this.nuxt.callHook('modules:done', this);
62 }
63
64 addVendor () {
65 consola__default['default'].warn('addVendor has been deprecated due to webpack4 optimization');
66 }
67
68 addTemplate (template) {
69 if (!template) {
70 throw new Error('Invalid template: ' + JSON.stringify(template))
71 }
72
73 // Validate & parse source
74 const src = template.src || template;
75 const srcPath = path__default['default'].parse(src);
76
77 if (typeof src !== 'string' || !fs__default['default'].existsSync(src)) {
78 throw new Error('Template src not found: ' + src)
79 }
80
81 // Mostly for DX, some people prefers `filename` vs `fileName`
82 const fileName = template.fileName || template.filename;
83 // Generate unique and human readable dst filename if not provided
84 const dst = fileName || `${path__default['default'].basename(srcPath.dir)}.${srcPath.name}.${hash__default['default'](src)}${srcPath.ext}`;
85 // Add to templates list
86 const templateObj = {
87 src,
88 dst,
89 options: template.options
90 };
91
92 this.options.build.templates.push(templateObj);
93
94 return templateObj
95 }
96
97 addPlugin (template) {
98 const { dst } = this.addTemplate(template);
99
100 // Add to nuxt plugins
101 this.options.plugins.unshift({
102 src: path__default['default'].join(this.options.buildDir, dst),
103 // TODO: remove deprecated option in Nuxt 3
104 ssr: template.ssr,
105 mode: template.mode
106 });
107 }
108
109 addLayout (template, name) {
110 const { dst, src } = this.addTemplate(template);
111 const layoutName = name || path__default['default'].parse(src).name;
112 const layout = this.options.layouts[layoutName];
113
114 if (layout) {
115 consola__default['default'].warn(`Duplicate layout registration, "${layoutName}" has been registered as "${layout}"`);
116 }
117
118 // Add to nuxt layouts
119 this.options.layouts[layoutName] = `./${dst}`;
120
121 // If error layout, set ErrorPage
122 if (name === 'error') {
123 this.addErrorLayout(dst);
124 }
125 }
126
127 addErrorLayout (dst) {
128 const relativeBuildDir = path__default['default'].relative(this.options.rootDir, this.options.buildDir);
129 this.options.ErrorPage = `~/${relativeBuildDir}/${dst}`;
130 }
131
132 addServerMiddleware (middleware) {
133 this.options.serverMiddleware.push(middleware);
134 }
135
136 extendBuild (fn) {
137 this.options.build.extend = utilsEdge.chainFn(this.options.build.extend, fn);
138 }
139
140 extendRoutes (fn) {
141 this.options.router.extendRoutes = utilsEdge.chainFn(
142 this.options.router.extendRoutes,
143 fn
144 );
145 }
146
147 requireModule (moduleOpts) {
148 return this.addModule(moduleOpts)
149 }
150
151 async addModule (moduleOpts) {
152 let src;
153 let options;
154 let handler;
155
156 // Type 1: String or Function
157 if (typeof moduleOpts === 'string' || typeof moduleOpts === 'function') {
158 src = moduleOpts;
159 } else if (Array.isArray(moduleOpts)) {
160 // Type 2: Babel style array
161 [src, options] = moduleOpts;
162 } else if (typeof moduleOpts === 'object') {
163 // Type 3: Pure object
164 ({ src, options, handler } = moduleOpts);
165 }
166
167 // Define handler if src is a function
168 if (typeof src === 'function') {
169 handler = src;
170 }
171
172 // Prevent adding buildModules-listed entries in production
173 if (this.options.buildModules.includes(handler) && this.options._start) {
174 return
175 }
176
177 // Resolve handler
178 if (!handler) {
179 try {
180 handler = this.nuxt.resolver.requireModule(src, { useESM: true });
181 } catch (error) {
182 if (error.code !== 'MODULE_NOT_FOUND') {
183 throw error
184 }
185
186 // Hint only if entrypoint is not found and src is not local alias or path
187 if (error.message.includes(src) && !/^[~.]|^@\//.test(src)) {
188 let message = 'Module `{name}` not found.';
189
190 if (this.options.buildModules.includes(src)) {
191 message += ' Please ensure `{name}` is in `devDependencies` and installed. HINT: During build step, for npm/yarn, `NODE_ENV=production` or `--production` should NOT be used.'.replace('{name}', src);
192 } else if (this.options.modules.includes(src)) {
193 message += ' Please ensure `{name}` is in `dependencies` and installed.';
194 }
195
196 message = message.replace(/{name}/g, src);
197
198 consola__default['default'].warn(message);
199 }
200
201 if (this.options._cli) {
202 throw error
203 } else {
204 // TODO: Remove in next major version
205 consola__default['default'].warn('Silently ignoring module as programatic usage detected.');
206 return
207 }
208 }
209 }
210
211 // Validate handler
212 if (typeof handler !== 'function') {
213 throw new TypeError('Module should export a function: ' + src)
214 }
215
216 // Ensure module is required once
217 const metaKey = handler.meta && handler.meta.name;
218 const key = metaKey || src;
219 if (typeof key === 'string') {
220 if (this.requiredModules[key]) {
221 if (!metaKey) {
222 // TODO: Skip with nuxt3
223 consola__default['default'].warn('Modules should be only specified once:', key);
224 } else {
225 return
226 }
227 }
228 this.requiredModules[key] = { src, options, handler };
229 }
230
231 // Default module options to empty object
232 if (options === undefined) {
233 options = {};
234 }
235 const result = await handler.call(this, options);
236 return result
237 }
238}
239
240var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
241
242/** Detect free variable `global` from Node.js. */
243var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
244
245var _freeGlobal = freeGlobal;
246
247/** Detect free variable `self`. */
248var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
249
250/** Used as a reference to the global object. */
251var root = _freeGlobal || freeSelf || Function('return this')();
252
253var _root = root;
254
255/** Built-in value references. */
256var Symbol = _root.Symbol;
257
258var _Symbol = Symbol;
259
260/** Used for built-in method references. */
261var objectProto = Object.prototype;
262
263/** Used to check objects for own properties. */
264var hasOwnProperty = objectProto.hasOwnProperty;
265
266/**
267 * Used to resolve the
268 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
269 * of values.
270 */
271var nativeObjectToString = objectProto.toString;
272
273/** Built-in value references. */
274var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
275
276/**
277 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
278 *
279 * @private
280 * @param {*} value The value to query.
281 * @returns {string} Returns the raw `toStringTag`.
282 */
283function getRawTag(value) {
284 var isOwn = hasOwnProperty.call(value, symToStringTag),
285 tag = value[symToStringTag];
286
287 try {
288 value[symToStringTag] = undefined;
289 var unmasked = true;
290 } catch (e) {}
291
292 var result = nativeObjectToString.call(value);
293 if (unmasked) {
294 if (isOwn) {
295 value[symToStringTag] = tag;
296 } else {
297 delete value[symToStringTag];
298 }
299 }
300 return result;
301}
302
303var _getRawTag = getRawTag;
304
305/** Used for built-in method references. */
306var objectProto$1 = Object.prototype;
307
308/**
309 * Used to resolve the
310 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
311 * of values.
312 */
313var nativeObjectToString$1 = objectProto$1.toString;
314
315/**
316 * Converts `value` to a string using `Object.prototype.toString`.
317 *
318 * @private
319 * @param {*} value The value to convert.
320 * @returns {string} Returns the converted string.
321 */
322function objectToString(value) {
323 return nativeObjectToString$1.call(value);
324}
325
326var _objectToString = objectToString;
327
328/** `Object#toString` result references. */
329var nullTag = '[object Null]',
330 undefinedTag = '[object Undefined]';
331
332/** Built-in value references. */
333var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
334
335/**
336 * The base implementation of `getTag` without fallbacks for buggy environments.
337 *
338 * @private
339 * @param {*} value The value to query.
340 * @returns {string} Returns the `toStringTag`.
341 */
342function baseGetTag(value) {
343 if (value == null) {
344 return value === undefined ? undefinedTag : nullTag;
345 }
346 return (symToStringTag$1 && symToStringTag$1 in Object(value))
347 ? _getRawTag(value)
348 : _objectToString(value);
349}
350
351var _baseGetTag = baseGetTag;
352
353/**
354 * Creates a unary function that invokes `func` with its argument transformed.
355 *
356 * @private
357 * @param {Function} func The function to wrap.
358 * @param {Function} transform The argument transform.
359 * @returns {Function} Returns the new function.
360 */
361function overArg(func, transform) {
362 return function(arg) {
363 return func(transform(arg));
364 };
365}
366
367var _overArg = overArg;
368
369/** Built-in value references. */
370var getPrototype = _overArg(Object.getPrototypeOf, Object);
371
372var _getPrototype = getPrototype;
373
374/**
375 * Checks if `value` is object-like. A value is object-like if it's not `null`
376 * and has a `typeof` result of "object".
377 *
378 * @static
379 * @memberOf _
380 * @since 4.0.0
381 * @category Lang
382 * @param {*} value The value to check.
383 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
384 * @example
385 *
386 * _.isObjectLike({});
387 * // => true
388 *
389 * _.isObjectLike([1, 2, 3]);
390 * // => true
391 *
392 * _.isObjectLike(_.noop);
393 * // => false
394 *
395 * _.isObjectLike(null);
396 * // => false
397 */
398function isObjectLike(value) {
399 return value != null && typeof value == 'object';
400}
401
402var isObjectLike_1 = isObjectLike;
403
404/** `Object#toString` result references. */
405var objectTag = '[object Object]';
406
407/** Used for built-in method references. */
408var funcProto = Function.prototype,
409 objectProto$2 = Object.prototype;
410
411/** Used to resolve the decompiled source of functions. */
412var funcToString = funcProto.toString;
413
414/** Used to check objects for own properties. */
415var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
416
417/** Used to infer the `Object` constructor. */
418var objectCtorString = funcToString.call(Object);
419
420/**
421 * Checks if `value` is a plain object, that is, an object created by the
422 * `Object` constructor or one with a `[[Prototype]]` of `null`.
423 *
424 * @static
425 * @memberOf _
426 * @since 0.8.0
427 * @category Lang
428 * @param {*} value The value to check.
429 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
430 * @example
431 *
432 * function Foo() {
433 * this.a = 1;
434 * }
435 *
436 * _.isPlainObject(new Foo);
437 * // => false
438 *
439 * _.isPlainObject([1, 2, 3]);
440 * // => false
441 *
442 * _.isPlainObject({ 'x': 0, 'y': 0 });
443 * // => true
444 *
445 * _.isPlainObject(Object.create(null));
446 * // => true
447 */
448function isPlainObject(value) {
449 if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag) {
450 return false;
451 }
452 var proto = _getPrototype(value);
453 if (proto === null) {
454 return true;
455 }
456 var Ctor = hasOwnProperty$1.call(proto, 'constructor') && proto.constructor;
457 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
458 funcToString.call(Ctor) == objectCtorString;
459}
460
461var isPlainObject_1 = isPlainObject;
462
463var version = "2.14.8-26735067.baf94d31";
464
465class Resolver {
466 constructor (nuxt) {
467 this.nuxt = nuxt;
468 this.options = this.nuxt.options;
469
470 // Binds
471 this.resolvePath = this.resolvePath.bind(this);
472 this.resolveAlias = this.resolveAlias.bind(this);
473 this.resolveModule = this.resolveModule.bind(this);
474 this.requireModule = this.requireModule.bind(this);
475
476 const { createRequire } = this.options;
477 this._require = createRequire ? createRequire(module) : module.require;
478
479 this._resolve = require.resolve;
480 }
481
482 resolveModule (path) {
483 try {
484 return this._resolve(path, {
485 paths: this.options.modulesDir
486 })
487 } catch (error) {
488 if (error.code !== 'MODULE_NOT_FOUND') {
489 // TODO: remove after https://github.com/facebook/jest/pull/8487 released
490 if (process.env.NODE_ENV === 'test' && error.message.startsWith('Cannot resolve module')) {
491 return
492 }
493 throw error
494 }
495 }
496 }
497
498 resolveAlias (path$1) {
499 if (utilsEdge.startsWithRootAlias(path$1)) {
500 return path.join(this.options.rootDir, path$1.substr(2))
501 }
502
503 if (utilsEdge.startsWithSrcAlias(path$1)) {
504 return path.join(this.options.srcDir, path$1.substr(1))
505 }
506
507 return path.resolve(this.options.srcDir, path$1)
508 }
509
510 resolvePath (path$1, { alias, isAlias = alias, module, isModule = module, isStyle } = {}) {
511 // TODO: Remove in Nuxt 3
512 if (alias) {
513 consola__default['default'].warn('Using alias is deprecated and will be removed in Nuxt 3. Use `isAlias` instead.');
514 }
515 if (module) {
516 consola__default['default'].warn('Using module is deprecated and will be removed in Nuxt 3. Use `isModule` instead.');
517 }
518
519 // Fast return in case of path exists
520 if (fs__default$1['default'].existsSync(path$1)) {
521 return path$1
522 }
523
524 let resolvedPath;
525
526 // Try to resolve it as a regular module
527 if (isModule !== false) {
528 resolvedPath = this.resolveModule(path$1);
529 }
530
531 // Try to resolve alias
532 if (!resolvedPath && isAlias !== false) {
533 resolvedPath = this.resolveAlias(path$1);
534 }
535
536 // Use path for resolvedPath
537 if (!resolvedPath) {
538 resolvedPath = path$1;
539 }
540
541 let isDirectory;
542
543 // Check if resolvedPath exits and is not a directory
544 if (fs__default$1['default'].existsSync(resolvedPath)) {
545 isDirectory = fs__default$1['default'].lstatSync(resolvedPath).isDirectory();
546
547 if (!isDirectory) {
548 return resolvedPath
549 }
550 }
551
552 const extensions = isStyle ? this.options.styleExtensions : this.options.extensions;
553
554 // Check if any resolvedPath.[ext] or resolvedPath/index.[ext] exists
555 for (const ext of extensions) {
556 if (!isDirectory && fs__default$1['default'].existsSync(resolvedPath + '.' + ext)) {
557 return resolvedPath + '.' + ext
558 }
559
560 const resolvedPathwithIndex = path.join(resolvedPath, 'index.' + ext);
561 if (isDirectory && fs__default$1['default'].existsSync(resolvedPathwithIndex)) {
562 return resolvedPathwithIndex
563 }
564 }
565
566 // If there's no index.[ext] we just return the directory path
567 if (isDirectory) {
568 return resolvedPath
569 }
570
571 // Give up
572 throw new Error(`Cannot resolve "${path$1}" from "${resolvedPath}"`)
573 }
574
575 requireModule (path, { esm, useESM = esm, alias, isAlias = alias, intropDefault, interopDefault = intropDefault } = {}) {
576 let resolvedPath = path;
577 let requiredModule;
578
579 // TODO: Remove in Nuxt 3
580 if (intropDefault) {
581 consola__default['default'].warn('Using intropDefault is deprecated and will be removed in Nuxt 3. Use `interopDefault` instead.');
582 }
583 if (alias) {
584 consola__default['default'].warn('Using alias is deprecated and will be removed in Nuxt 3. Use `isAlias` instead.');
585 }
586 if (esm) {
587 consola__default['default'].warn('Using esm is deprecated and will be removed in Nuxt 3. Use `useESM` instead.');
588 }
589
590 let lastError;
591
592 // Try to resolve path
593 try {
594 resolvedPath = this.resolvePath(path, { isAlias });
595 } catch (e) {
596 lastError = e;
597 }
598
599 const isExternal = utilsEdge.isExternalDependency(resolvedPath);
600
601 // in dev mode make sure to clear the require cache so after
602 // a dev server restart any changed file is reloaded
603 if (this.options.dev && !isExternal) {
604 utilsEdge.clearRequireCache(resolvedPath);
605 }
606
607 // By default use esm only for js,mjs files outside of node_modules
608 if (useESM === undefined) {
609 useESM = !isExternal && /.(js|mjs)$/.test(resolvedPath);
610 }
611
612 // Try to require
613 try {
614 if (useESM) {
615 requiredModule = this._require(resolvedPath);
616 } else {
617 requiredModule = require(resolvedPath);
618 }
619 } catch (e) {
620 lastError = e;
621 }
622
623 // Interop default
624 if (interopDefault !== false && requiredModule && requiredModule.default) {
625 requiredModule = requiredModule.default;
626 }
627
628 // Throw error if failed to require
629 if (requiredModule === undefined && lastError) {
630 throw lastError
631 }
632
633 return requiredModule
634 }
635}
636
637class Nuxt extends Hookable__default['default'] {
638 constructor (options = {}) {
639 super(consola__default['default']);
640
641 // Assign options and apply defaults
642 this.options = configEdge.getNuxtConfig(options);
643
644 // Create instance of core components
645 this.resolver = new Resolver(this);
646 this.moduleContainer = new ModuleContainer(this);
647
648 // Deprecated hooks
649 this.deprecateHooks({
650 // #3294 - 7514db73b25c23b8c14ebdafbb4e129ac282aabd
651 'render:context': {
652 to: '_render:context',
653 message: '`render:context(nuxt)` is deprecated, Please use `vue-renderer:ssr:context(context)`'
654 },
655 // #3773
656 'render:routeContext': {
657 to: '_render:context',
658 message: '`render:routeContext(nuxt)` is deprecated, Please use `vue-renderer:ssr:context(context)`'
659 },
660 showReady: 'webpack:done',
661 // Introduced in 2.13
662 'export:done': 'generate:done',
663 'export:before': 'generate:before',
664 'export:extendRoutes': 'generate:extendRoutes',
665 'export:distRemoved': 'generate:distRemoved',
666 'export:distCopied': 'generate:distCopied',
667 'export:route': 'generate:route',
668 'export:routeFailed': 'generate:routeFailed',
669 'export:page': 'generate:page',
670 'export:routeCreated': 'generate:routeCreated'
671 });
672
673 // Add Legacy aliases
674 utilsEdge.defineAlias(this, this.resolver, ['resolveAlias', 'resolvePath']);
675 this.showReady = () => { this.callHook('webpack:done'); };
676
677 // Init server
678 if (this.options.server !== false) {
679 this._initServer();
680 }
681
682 // Call ready
683 if (this.options._ready !== false) {
684 this.ready().catch((err) => {
685 consola__default['default'].fatal(err);
686 });
687 }
688 }
689
690 static get version () {
691 return `v${version}` + (global.__NUXT_DEV__ ? '-development' : '')
692 }
693
694 ready () {
695 if (!this._ready) {
696 this._ready = this._init();
697 }
698 return this._ready
699 }
700
701 async _init () {
702 if (this._initCalled) {
703 return this
704 }
705 this._initCalled = true;
706
707 // Add hooks
708 if (isPlainObject_1(this.options.hooks)) {
709 this.addHooks(this.options.hooks);
710 } else if (typeof this.options.hooks === 'function') {
711 this.options.hooks(this.hook);
712 }
713
714 // Await for modules
715 await this.moduleContainer.ready();
716
717 // Await for server to be ready
718 if (this.server) {
719 await this.server.ready();
720 }
721
722 // Call ready hook
723 await this.callHook('ready', this);
724
725 return this
726 }
727
728 _initServer () {
729 if (this.server) {
730 return
731 }
732 this.server = new serverEdge.Server(this);
733 this.renderer = this.server;
734 this.render = this.server.app;
735 utilsEdge.defineAlias(this, this.server, ['renderRoute', 'renderAndGetWindow', 'listen']);
736 }
737
738 async close (callback) {
739 await this.callHook('close', this);
740
741 if (typeof callback === 'function') {
742 await callback();
743 }
744
745 this.clearHooks();
746 }
747}
748
749const OVERRIDES = {
750 dry: { dev: false, server: false },
751 dev: { dev: true, _build: true },
752 build: { dev: false, server: false, _build: true },
753 start: { dev: false, _start: true }
754};
755
756async function loadNuxt (loadOptions) {
757 // Normalize loadOptions
758 if (typeof loadOptions === 'string') {
759 loadOptions = { for: loadOptions };
760 }
761 const { ready = true } = loadOptions;
762 const _for = loadOptions.for || 'dry';
763
764 // Get overrides
765 const override = OVERRIDES[_for];
766
767 // Unsupported purpose
768 if (!override) {
769 throw new Error('Unsupported for: ' + _for)
770 }
771
772 // Load Config
773 const config = await configEdge.loadNuxtConfig(loadOptions);
774
775 // Apply config overrides
776 Object.assign(config, override);
777
778 // Initiate Nuxt
779 const nuxt = new Nuxt(config);
780 if (ready) {
781 await nuxt.ready();
782 }
783
784 return nuxt
785}
786
787Object.defineProperty(exports, 'loadNuxtConfig', {
788 enumerable: true,
789 get: function () {
790 return configEdge.loadNuxtConfig;
791 }
792});
793exports.Module = ModuleContainer;
794exports.Nuxt = Nuxt;
795exports.Resolver = Resolver;
796exports.loadNuxt = loadNuxt;