UNPKG

@parcel/core

Version:
349 lines (346 loc) • 13.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResolverRunner = void 0; exports.default = createPathRequest; function _diagnostic() { const data = _interopRequireWildcard(require("@parcel/diagnostic")); _diagnostic = function () { return data; }; return data; } function _logger() { const data = require("@parcel/logger"); _logger = function () { return data; }; return data; } function _nullthrows() { const data = _interopRequireDefault(require("nullthrows")); _nullthrows = function () { return data; }; return data; } function _path() { const data = _interopRequireDefault(require("path")); _path = function () { return data; }; return data; } function _utils() { const data = require("@parcel/utils"); _utils = function () { return data; }; return data; } var _ReporterRunner = require("../ReporterRunner"); var _Dependency = require("../public/Dependency"); var _PluginOptions = _interopRequireDefault(require("../public/PluginOptions")); var _ParcelConfig = _interopRequireDefault(require("../ParcelConfig")); var _ParcelConfigRequest = _interopRequireWildcard(require("./ParcelConfigRequest")); var _utils2 = require("../utils"); var _projectPath = require("../projectPath"); var _types = require("../types"); var _buildCache = require("../buildCache"); var _InternalConfig = require("../InternalConfig"); var _ConfigRequest = require("./ConfigRequest"); var _DevDepRequest = require("./DevDepRequest"); function _profiler() { const data = require("@parcel/profiler"); _profiler = function () { return data; }; return data; } var _RequestTracker = require("../RequestTracker"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const PIPELINE_REGEX = /^([a-z0-9-]+?):(.*)$/i; function createPathRequest(input) { return { id: input.dependency.id + ':' + input.name, type: _RequestTracker.requestTypes.path_request, run, input }; } async function run({ input, api, options }) { let configResult = (0, _nullthrows().default)(await api.runRequest((0, _ParcelConfigRequest.default)())); let config = (0, _ParcelConfigRequest.getCachedParcelConfig)(configResult, options); let { devDeps, invalidDevDeps } = await (0, _DevDepRequest.getDevDepRequests)(api); (0, _DevDepRequest.invalidateDevDeps)(invalidDevDeps, options, config); let resolverRunner = new ResolverRunner({ options, config, previousDevDeps: devDeps }); let result = await resolverRunner.resolve(input.dependency); if (result.invalidateOnEnvChange) { for (let env of result.invalidateOnEnvChange) { api.invalidateOnEnvChange(env); } } if (result.invalidateOnFileCreate) { for (let file of result.invalidateOnFileCreate) { api.invalidateOnFileCreate((0, _utils2.invalidateOnFileCreateToInternal)(options.projectRoot, file)); } } if (result.invalidateOnFileChange) { for (let filePath of result.invalidateOnFileChange) { let pp = (0, _projectPath.toProjectPath)(options.projectRoot, filePath); api.invalidateOnFileUpdate(pp); api.invalidateOnFileDelete(pp); } } for (let config of resolverRunner.configs.values()) { await (0, _ConfigRequest.runConfigRequest)(api, config); } for (let devDepRequest of resolverRunner.devDepRequests.values()) { await (0, _DevDepRequest.runDevDepRequest)(api, devDepRequest); } if (result.assetGroup) { api.invalidateOnFileDelete(result.assetGroup.filePath); return result.assetGroup; } if (result.diagnostics && result.diagnostics.length > 0) { let err = new (_diagnostic().default)({ diagnostic: result.diagnostics }); // $FlowFixMe[prop-missing] err.code = 'MODULE_NOT_FOUND'; throw err; } } const configCache = (0, _buildCache.createBuildCache)(); class ResolverRunner { constructor({ config, options, previousDevDeps }) { this.config = config; this.options = options; this.pluginOptions = new _PluginOptions.default(this.options); this.previousDevDeps = previousDevDeps; this.devDepRequests = new Map(); this.configs = new Map(); } async getDiagnostic(dependency, message) { let diagnostic = { message, origin: '@parcel/core' }; if (dependency.loc && dependency.sourcePath != null) { let filePath = (0, _projectPath.fromProjectPath)(this.options.projectRoot, dependency.sourcePath); diagnostic.codeFrames = [{ filePath, code: await this.options.inputFS.readFile(filePath, 'utf8').catch(() => ''), codeHighlights: dependency.loc ? [(0, _diagnostic().convertSourceLocationToHighlight)(dependency.loc)] : [] }]; } return diagnostic; } async loadConfigs(resolvers) { for (let plugin of resolvers) { // Only load config for a plugin once per build. let config = configCache.get(plugin.name); if (!config && plugin.plugin.loadConfig != null) { config = (0, _InternalConfig.createConfig)({ plugin: plugin.name, searchPath: (0, _projectPath.toProjectPathUnsafe)('index') }); await (0, _ConfigRequest.loadPluginConfig)(plugin, config, this.options); configCache.set(plugin.name, config); this.configs.set(plugin.name, config); } if (config) { for (let devDep of config.devDeps) { let devDepRequest = await (0, _DevDepRequest.createDevDependency)(devDep, this.previousDevDeps, this.options); this.runDevDepRequest(devDepRequest); } this.configs.set(plugin.name, config); } } } runDevDepRequest(devDepRequest) { let { specifier, resolveFrom } = devDepRequest; let key = `${specifier}:${(0, _projectPath.fromProjectPathRelative)(resolveFrom)}`; this.devDepRequests.set(key, devDepRequest); } async resolve(dependency) { let dep = (0, _Dependency.getPublicDependency)(dependency, this.options); (0, _ReporterRunner.report)({ type: 'buildProgress', phase: 'resolving', dependency: dep }); let resolvers = await this.config.getResolvers(); await this.loadConfigs(resolvers); let pipeline; let specifier; let validPipelines = new Set(this.config.getNamedPipelines()); let match = dependency.specifier.match(PIPELINE_REGEX); if (match && // Don't consider absolute paths. Absolute paths are only supported for entries, // and include e.g. `C:\` on Windows, conflicting with pipelines. !_path().default.isAbsolute(dependency.specifier)) { [, pipeline, specifier] = match; if (!validPipelines.has(pipeline)) { // This may be a url protocol or scheme rather than a pipeline, such as // `url('http://example.com/foo.png')`. Pass it to resolvers to handle. specifier = dependency.specifier; pipeline = null; } } else { specifier = dependency.specifier; } // Entrypoints, convert ProjectPath in module specifier to absolute path if (dep.resolveFrom == null) { specifier = _path().default.join(this.options.projectRoot, specifier); } let diagnostics = []; let invalidateOnFileCreate = []; let invalidateOnFileChange = []; let invalidateOnEnvChange = []; for (let resolver of resolvers) { let measurement; try { var _this$configs$get; measurement = _profiler().tracer.createMeasurement(resolver.name, 'resolve', specifier); let result = await resolver.plugin.resolve({ specifier, pipeline, dependency: dep, options: this.pluginOptions, logger: new (_logger().PluginLogger)({ origin: resolver.name }), tracer: new (_profiler().PluginTracer)({ origin: resolver.name, category: 'resolver' }), config: (_this$configs$get = this.configs.get(resolver.name)) === null || _this$configs$get === void 0 ? void 0 : _this$configs$get.result }); measurement && measurement.end(); if (result) { if (result.meta) { dependency.resolverMeta = result.meta; dependency.meta = { ...dependency.meta, ...result.meta }; } if (result.priority != null) { dependency.priority = dependency.resolverPriority = _types.Priority[result.priority]; } if (result.invalidateOnEnvChange) { invalidateOnEnvChange.push(...result.invalidateOnEnvChange); } if (result.invalidateOnFileCreate) { invalidateOnFileCreate.push(...result.invalidateOnFileCreate); } if (result.invalidateOnFileChange) { invalidateOnFileChange.push(...result.invalidateOnFileChange); } if (result.isExcluded) { return { assetGroup: null, invalidateOnFileCreate, invalidateOnFileChange, invalidateOnEnvChange }; } if (result.filePath != null) { var _result$query; let resultFilePath = result.filePath; if (!_path().default.isAbsolute(resultFilePath)) { throw new Error((0, _diagnostic().md)`Resolvers must return an absolute path, ${resolver.name} returned: ${resultFilePath}`); } return { assetGroup: { canDefer: result.canDefer, filePath: (0, _projectPath.toProjectPath)(this.options.projectRoot, resultFilePath), query: (_result$query = result.query) === null || _result$query === void 0 ? void 0 : _result$query.toString(), sideEffects: result.sideEffects, code: result.code, env: dependency.env, pipeline: result.pipeline === undefined ? pipeline ?? dependency.pipeline : result.pipeline, isURL: dep.specifierType === 'url' }, invalidateOnFileCreate, invalidateOnFileChange, invalidateOnEnvChange }; } if (result.diagnostics != null && !(Array.isArray(result.diagnostics) && result.diagnostics.length === 0)) { let errorDiagnostic = (0, _diagnostic().errorToDiagnostic)(new (_diagnostic().default)({ diagnostic: result.diagnostics }), { origin: resolver.name, filePath: specifier }); diagnostics.push(...errorDiagnostic); } } } catch (e) { // Add error to error map, we'll append these to the standard error if we can't resolve the asset let errorDiagnostic = (0, _diagnostic().errorToDiagnostic)(e, { origin: resolver.name, filePath: specifier }); if (Array.isArray(errorDiagnostic)) { diagnostics.push(...errorDiagnostic); } else { diagnostics.push(errorDiagnostic); } break; } finally { measurement && measurement.end(); // Add dev dependency for the resolver. This must be done AFTER running it due to // the potential for lazy require() that aren't executed until the request runs. let devDepRequest = await (0, _DevDepRequest.createDevDependency)({ specifier: resolver.name, resolveFrom: resolver.resolveFrom }, this.previousDevDeps, this.options); this.runDevDepRequest(devDepRequest); } } if (dep.isOptional) { return { assetGroup: null, invalidateOnFileCreate, invalidateOnFileChange, invalidateOnEnvChange }; } let resolveFrom = dependency.resolveFrom ?? dependency.sourcePath; let dir = resolveFrom != null ? (0, _utils().normalizePath)((0, _projectPath.fromProjectPathRelative)(resolveFrom)) : ''; let diagnostic = await this.getDiagnostic(dependency, (0, _diagnostic().md)`Failed to resolve '${dependency.specifier}' ${dir ? `from '${dir}'` : ''}`); diagnostics.unshift(diagnostic); return { assetGroup: null, invalidateOnFileCreate, invalidateOnFileChange, invalidateOnEnvChange, diagnostics }; } } exports.ResolverRunner = ResolverRunner;