| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 | const { attrsToQuery, genMatchResource } = require('./utils')const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api'))const nonWhitespaceRE = /\S+/module.exports = function genStyleInjectionCode(  loaderContext,  styles,  id,  resourcePath,  stringifyRequest,  needsHotReload,  needsExplicitInjection,  isProduction,  enableInlineMatchResource) {  let styleImportsCode = ``  let styleInjectionCode = ``  let cssModulesHotReloadCode = ``  let hasCSSModules = false  const cssModuleNames = new Map()  function genStyleRequest(style, i) {    const src = style.src || resourcePath    const attrsQuery = attrsToQuery(style.attrs, 'css')    const lang = String(style.attrs.lang || 'css')    const inheritQuery = loaderContext.resourceQuery.slice(1)      ? `&${loaderContext.resourceQuery.slice(1)}`      : ''    // make sure to only pass id not src importing so that we don't inject    // duplicate tags when multiple components import the same css file    const idQuery = !style.src || style.scoped ? `&id=${id}` : ``    const prodQuery = isProduction ? `&prod` : ``    const externalQuery = style.src ? `&external` : ``    const query = `?vue&type=style&index=${i}${idQuery}${prodQuery}${attrsQuery}${inheritQuery}${externalQuery}`    let styleRequest    if (enableInlineMatchResource) {      styleRequest = stringifyRequest(genMatchResource(loaderContext, src, query, lang))    } else {      styleRequest = stringifyRequest(src + query)    }    return styleRequest  }  function genCSSModulesCode(style, request, i) {    hasCSSModules = true    const moduleName = style.module === true ? '$style' : style.module    if (cssModuleNames.has(moduleName)) {      loaderContext.emitError(`CSS module name ${moduleName} is not unique!`)    }    cssModuleNames.set(moduleName, true)    // `(vue-)style-loader` exports the name-to-hash map directly    // `css-loader` exports it in `.locals`    const locals = `(style${i}.locals || style${i})`    const name = JSON.stringify(moduleName)    if (!needsHotReload) {      styleInjectionCode += `this[${name}] = ${locals}\n`    } else {      styleInjectionCode += `        cssModules[${name}] = ${locals}        Object.defineProperty(this, ${name}, {          configurable: true,          get: function () {            return cssModules[${name}]          }        })      `      cssModulesHotReloadCode += `        module.hot && module.hot.accept([${request}], function () {          var oldLocals = cssModules[${name}]          if (oldLocals) {            var newLocals = require(${request})            if (JSON.stringify(newLocals) !== JSON.stringify(oldLocals)) {              cssModules[${name}] = newLocals              require(${hotReloadAPIPath}).rerender("${id}")            }          }        })      `    }  }  // empty styles: with no `src` specified or only contains whitespaces  const isNotEmptyStyle = (style) =>    style.src || nonWhitespaceRE.test(style.content)  // explicit injection is needed in SSR (for critical CSS collection)  // or in Shadow Mode (for injection into shadow root)  // In these modes, vue-style-loader exports objects with the __inject__  // method; otherwise we simply import the styles.  if (!needsExplicitInjection) {    styles.forEach((style, i) => {      // do not generate requests for empty styles      if (isNotEmptyStyle(style)) {        const request = genStyleRequest(style, i)        styleImportsCode += `import style${i} from ${request}\n`        if (style.module) genCSSModulesCode(style, request, i)      }    })  } else {    styles.forEach((style, i) => {      if (isNotEmptyStyle(style)) {        const request = genStyleRequest(style, i)        styleInjectionCode +=          `var style${i} = require(${request})\n` +          `if (style${i}.__inject__) style${i}.__inject__(context)\n`        if (style.module) genCSSModulesCode(style, request, i)      }    })  }  if (!needsExplicitInjection && !hasCSSModules) {    return styleImportsCode  }  return `${styleImportsCode}${hasCSSModules && needsHotReload ? `var cssModules = {}` : ``}${needsHotReload ? `var disposed = false` : ``}function injectStyles (context) {  ${needsHotReload ? `if (disposed) return` : ``}  ${styleInjectionCode}}${  needsHotReload    ? `  module.hot && module.hot.dispose(function (data) {    disposed = true  })`    : ``}${cssModulesHotReloadCode}  `.trim()}
 |