aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vue-loader/lib/loaders/pitcher.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/vue-loader/lib/loaders/pitcher.js')
-rw-r--r--node_modules/vue-loader/lib/loaders/pitcher.js144
1 files changed, 144 insertions, 0 deletions
diff --git a/node_modules/vue-loader/lib/loaders/pitcher.js b/node_modules/vue-loader/lib/loaders/pitcher.js
new file mode 100644
index 00000000..0bc77046
--- /dev/null
+++ b/node_modules/vue-loader/lib/loaders/pitcher.js
@@ -0,0 +1,144 @@
+const qs = require('querystring')
+const loaderUtils = require('loader-utils')
+const hash = require('hash-sum')
+const selfPath = require.resolve('../index')
+const templateLoaderPath = require.resolve('./templateLoader')
+const stylePostLoaderPath = require.resolve('./stylePostLoader')
+
+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 isPitcher = l => l.path !== __filename
+
+const dedupeESLintLoader = loaders => {
+ const res = []
+ let seen = false
+ loaders.forEach(l => {
+ if (!isESLintLoader(l)) {
+ res.push(l)
+ } else if (!seen) {
+ seen = true
+ res.push(l)
+ }
+ })
+ return res
+}
+
+module.exports = code => code
+
+// This pitching loader is responsible for intercepting all vue block requests
+// and transform it into appropriate requests.
+module.exports.pitch = function (remainingRequest) {
+ const options = loaderUtils.getOptions(this)
+ const { cacheDirectory, cacheIdentifier } = options
+ const query = qs.parse(this.resourceQuery.slice(1))
+
+ let loaders = this.loaders
+
+ // if this is a language block request, eslint-loader may get matched
+ // multiple times
+ if (query.type) {
+ // if this is an inline block, since the whole file itself is being linted,
+ // remove eslint-loader to avoid duplicate linting.
+ if (/\.vue$/.test(this.resourcePath)) {
+ loaders = loaders.filter(l => !isESLintLoader(l))
+ } else {
+ // This is a src import. Just make sure there's not more than 1 instance
+ // of eslint present.
+ loaders = dedupeESLintLoader(loaders)
+ }
+ }
+
+ // remove self
+ loaders = loaders.filter(isPitcher)
+
+ // do not inject if user uses null-loader to void the type (#1239)
+ if (loaders.some(isNullLoader)) {
+ return
+ }
+
+ const genRequest = loaders => {
+ // Important: dedupe since both the original rule
+ // and the cloned rule would match a source import request.
+ // also make sure to dedupe based on loader path.
+ // assumes you'd probably never want to apply the same loader on the same
+ // file twice.
+ // Exception: in Vue CLI we do need two instances of postcss-loader
+ // for user config and inline minification. So we need to dedupe baesd on
+ // path AND query to be safe.
+ const seen = new Map()
+ const loaderStrings = []
+
+ loaders.forEach(loader => {
+ const identifier = typeof loader === 'string'
+ ? loader
+ : (loader.path + loader.query)
+ const request = typeof loader === 'string' ? loader : loader.request
+ if (!seen.has(identifier)) {
+ seen.set(identifier, true)
+ // loader.request contains both the resolved loader path and its options
+ // query (e.g. ??ref-0)
+ loaderStrings.push(request)
+ }
+ })
+
+ return loaderUtils.stringifyRequest(this, '-!' + [
+ ...loaderStrings,
+ this.resourcePath + this.resourceQuery
+ ].join('!'))
+ }
+
+ // Inject style-post-loader before css-loader for scoped CSS and trimming
+ if (query.type === `style`) {
+ const cssLoaderIndex = loaders.findIndex(isCSSLoader)
+ if (cssLoaderIndex > -1) {
+ const afterLoaders = loaders.slice(0, cssLoaderIndex + 1)
+ const beforeLoaders = loaders.slice(cssLoaderIndex + 1)
+ const request = genRequest([
+ ...afterLoaders,
+ stylePostLoaderPath,
+ ...beforeLoaders
+ ])
+ // console.log(request)
+ return `import mod from ${request}; export default mod; export * from ${request}`
+ }
+ }
+
+ // for templates: inject the template compiler & optional cache
+ if (query.type === `template`) {
+ const path = require('path')
+ const cacheLoader = cacheDirectory && cacheIdentifier
+ ? [`cache-loader?${JSON.stringify({
+ // For some reason, webpack fails to generate consistent hash if we
+ // use absolute paths here, even though the path is only used in a
+ // comment. For now we have to ensure cacheDirectory is a relative path.
+ cacheDirectory: path.isAbsolute(cacheDirectory)
+ ? path.relative(process.cwd(), cacheDirectory)
+ : cacheDirectory,
+ cacheIdentifier: hash(cacheIdentifier) + '-vue-loader-template'
+ })}`]
+ : []
+ const request = genRequest([
+ ...cacheLoader,
+ templateLoaderPath + `??vue-loader-options`,
+ ...loaders
+ ])
+ // console.log(request)
+ // the template compiler uses esm exports
+ return `export * from ${request}`
+ }
+
+ // if a custom block has no other matching loader other than vue-loader itself,
+ // we should ignore it
+ if (query.type === `custom` &&
+ loaders.length === 1 &&
+ loaders[0].path === selfPath) {
+ return ``
+ }
+
+ // When the user defines a rule that has only resourceQuery but no test,
+ // both that rule and the cloned rule will match, resulting in duplicated
+ // loaders. Therefore it is necessary to perform a dedupe here.
+ const request = genRequest(loaders)
+ return `import mod from ${request}; export default mod; export * from ${request}`
+}