"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pitch = void 0; const qs = require("querystring"); const loaderUtils = require("loader-utils"); const selfPath = require.resolve('./index'); // const templateLoaderPath = require.resolve('./templateLoader') const stylePostLoaderPath = require.resolve('./stylePostLoader'); const styleInlineLoaderPath = require.resolve('./styleInlineLoader'); const isESLintLoader = (l) => /(\/|\\|@)eslint-loader/.test(l.path); const isNullLoader = (l) => /(\/|\\|@)null-loader/.test(l.path); const isCSSLoader = (l) => /(\/|\\|@)css-loader/.test(l.path); const isCacheLoader = (l) => /(\/|\\|@)cache-loader/.test(l.path); const isNotPitcher = (l) => l.path !== __filename; const pitcher = (code) => code; // This pitching loader is responsible for intercepting all vue block requests // and transform it into appropriate requests. const pitch = function () { const context = this; const rawLoaders = context.loaders.filter(isNotPitcher); let loaders = rawLoaders; // do not inject if user uses null-loader to void the type (#1239) if (loaders.some(isNullLoader)) { return; } const query = qs.parse(context.resourceQuery.slice(1)); const isInlineBlock = /\.vue$/.test(context.resourcePath); // eslint-loader may get matched multiple times // if this is an inline block, since the whole file itself is being linted, // remove eslint-loader to avoid duplicate linting. if (isInlineBlock) { loaders = loaders.filter((l) => !isESLintLoader(l)); } // Important: dedupe loaders since both the original rule // and the cloned rule would match a source import request or a // resourceQuery-only rule that intends to target a custom block with no lang const seen = new Map(); loaders = loaders.filter((loader) => { const identifier = typeof loader === 'string' ? loader : // Dedupe based on both path and query if available. This is important // in Vue CLI so that postcss-loaders with different options can co-exist loader.path + loader.query; if (!seen.has(identifier)) { seen.set(identifier, true); return true; } }); // Inject style-post-loader before css-loader for scoped CSS and trimming if (query.type === `style`) { const cssLoaderIndex = loaders.findIndex(isCSSLoader); if (cssLoaderIndex > -1) { // if inlined, ignore any loaders after css-loader and replace w/ inline // loader const afterLoaders = query.inline != null ? [styleInlineLoaderPath] : loaders.slice(0, cssLoaderIndex + 1); const beforeLoaders = loaders.slice(cssLoaderIndex + 1); return genProxyModule([...afterLoaders, stylePostLoaderPath, ...beforeLoaders], context, !!query.module || query.inline != null); } } // if a custom block has no other matching loader other than vue-loader itself // or cache-loader, we should ignore it if (query.type === `custom` && shouldIgnoreCustomBlock(loaders)) { return ``; } // Rewrite request. Technically this should only be done when we have deduped // loaders. But somehow this is required for block source maps to work. return genProxyModule(loaders, context, query.type !== 'template'); }; exports.pitch = pitch; function genProxyModule(loaders, context, exportDefault = true) { const request = genRequest(loaders, context); // return a proxy module which simply re-exports everything from the // actual request. Note for template blocks the compiled module has no // default export. return ((exportDefault ? `export { default } from ${request}; ` : ``) + `export * from ${request}`); } function genRequest(loaders, context) { const loaderStrings = loaders.map((loader) => { return typeof loader === 'string' ? loader : loader.request; }); const resource = context.resourcePath + context.resourceQuery; return loaderUtils.stringifyRequest(context, '-!' + [...loaderStrings, resource].join('!')); } function shouldIgnoreCustomBlock(loaders) { const actualLoaders = loaders.filter((loader) => { // vue-loader if (loader.path === selfPath) { return false; } // cache-loader if (isCacheLoader(loader)) { return false; } return true; }); return actualLoaders.length === 0; } exports.default = pitcher;