var path = require('path') var parse = require('./parser') var genId = require('./utils/gen-id') var normalize = require('./utils/normalize') var loaderUtils = require('loader-utils') var querystring = require('querystring') // internal lib loaders var selectorPath = normalize.lib('selector') var styleCompilerPath = normalize.lib('style-compiler/index') var templateCompilerPath = normalize.lib('template-compiler/index') var templatePreprocessorPath = normalize.lib('template-compiler/preprocessor') var componentNormalizerPath = normalize.lib('component-normalizer') // dep loaders var styleLoaderPath = normalize.dep('vue-style-loader') var hotReloadAPIPath = normalize.dep('vue-hot-reload-api') var hasBabel = false try { hasBabel = !!require('babel-loader') } catch (e) {} var hasBuble = false try { hasBuble = !!require('buble-loader') } catch (e) {} var rewriterInjectRE = /\b(css(?:-loader)?(?:\?[^!]+)?)(?:!|$)/ var defaultLang = { template: 'html', styles: 'css', script: 'js' } // When extracting parts from the source vue file, we want to apply the // loaders chained before vue-loader, but exclude some loaders that simply // produces side effects such as linting. function getRawRequest (context, excludedPreLoaders) { excludedPreLoaders = excludedPreLoaders || /eslint-loader/ return loaderUtils.getRemainingRequest({ resource: context.resource, loaderIndex: context.loaderIndex, loaders: context.loaders.filter(loader => !excludedPreLoaders.test(loader.path)) }) } module.exports = function (content) { this.cacheable() var isServer = this.target === 'node' var isProduction = this.minimize || process.env.NODE_ENV === 'production' var loaderContext = this var query = loaderUtils.getOptions(this) || {} var options = this.options.__vueOptions__ = Object.assign({}, this.options.vue, this.vue, query) var rawRequest = getRawRequest(this, options.excludedPreLoaders) var filePath = this.resourcePath var fileName = path.basename(filePath) var context = (this._compiler && this._compiler.context) || this.options.context || process.cwd() var moduleId = 'data-v-' + genId(filePath, context, options.hashKey) var cssLoaderOptions = '' if (!isProduction && this.sourceMap && options.cssSourceMap !== false) { cssLoaderOptions += '?sourceMap' } if (isProduction) { cssLoaderOptions += (cssLoaderOptions ? '&' : '?') + 'minimize' } var bubleOptions = hasBuble && options.buble ? '?' + JSON.stringify(options.buble) : '' var templateCompilerOptions = '?' + JSON.stringify({ id: moduleId, transformToRequire: options.transformToRequire, preserveWhitespace: options.preserveWhitespace, buble: options.buble, // only pass compilerModules if it's a path string compilerModules: typeof options.compilerModules === 'string' ? options.compilerModules : undefined }) var defaultLoaders = { html: templateCompilerPath + templateCompilerOptions, css: styleLoaderPath + '!' + 'css-loader' + cssLoaderOptions, js: hasBuble ? ('buble-loader' + bubleOptions) : hasBabel ? 'babel-loader' : '' } // check if there are custom loaders specified via // webpack config, otherwise use defaults var loaders = Object.assign({}, defaultLoaders, options.loaders) var preLoaders = options.preLoaders || {} var postLoaders = options.postLoaders || {} function getRequire (type, part, index, scoped) { return 'require(' + getRequireString(type, part, index, scoped) + ')' } function getRequireString (type, part, index, scoped) { return loaderUtils.stringifyRequest(loaderContext, // disable all configuration loaders '!!' + // get loader string for pre-processors getLoaderString(type, part, index, scoped) + // select the corresponding part from the vue file getSelectorString(type, index || 0) + // the url to the actual vue file, including remaining requests rawRequest ) } function getRequireForImport (type, impt, scoped) { return 'require(' + getRequireForImportString(type, impt, scoped) + ')' } function getRequireForImportString (type, impt, scoped) { return loaderUtils.stringifyRequest(loaderContext, '!!' + getLoaderString(type, impt, -1, scoped) + impt.src ) } function addCssModulesToLoader (loader, part, index) { if (!part.module) return loader var option = options.cssModules || {} var DEFAULT_OPTIONS = { modules: true, importLoaders: true } var OPTIONS = { localIdentName: '[hash:base64]' } return loader.replace(/((?:^|!)css(?:-loader)?)(\?[^!]*)?/, function (m, $1, $2) { // $1: !css-loader // $2: ?a=b var query = loaderUtils.parseQuery($2 || '?') Object.assign(query, OPTIONS, option, DEFAULT_OPTIONS) if (index !== -1) { // Note: // Class name is generated according to its filename. // Different