templateLoader.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. const qs = require('querystring')
  2. const loaderUtils = require('loader-utils')
  3. const { compileTemplate } = require('@vue/component-compiler-utils')
  4. // Loader that compiles raw template into JavaScript functions.
  5. // This is injected by the global pitcher (../pitch) for template
  6. // selection requests initiated from vue files.
  7. module.exports = function (source) {
  8. const loaderContext = this
  9. const query = qs.parse(this.resourceQuery.slice(1))
  10. // although this is not the main vue-loader, we can get access to the same
  11. // vue-loader options because we've set an ident in the plugin and used that
  12. // ident to create the request for this loader in the pitcher.
  13. const options = loaderUtils.getOptions(loaderContext) || {}
  14. const { id } = query
  15. const isServer = loaderContext.target === 'node'
  16. const isProduction = loaderContext.minimize || process.env.NODE_ENV === 'production'
  17. const isFunctional = query.functional
  18. // allow using custom compiler via options
  19. const compiler = options.compiler || require('vue-template-compiler')
  20. const compilerOptions = Object.assign({}, options.compilerOptions, {
  21. scopeId: query.scoped ? `data-v-${id}` : null,
  22. comments: query.comments
  23. })
  24. // for vue-component-compiler
  25. const finalOptions = {
  26. source,
  27. filename: this.resourcePath,
  28. compiler,
  29. compilerOptions,
  30. // allow customizing behavior of vue-template-es2015-compiler
  31. transpileOptions: options.transpileOptions,
  32. transformAssetUrls: options.transformAssetUrls || true,
  33. isProduction,
  34. isFunctional,
  35. optimizeSSR: isServer && options.optimizeSSR !== false
  36. }
  37. const compiled = compileTemplate(finalOptions)
  38. // tips
  39. if (compiled.tips && compiled.tips.length) {
  40. compiled.tips.forEach(tip => {
  41. loaderContext.emitWarning(tip)
  42. })
  43. }
  44. // errors
  45. if (compiled.errors && compiled.errors.length) {
  46. loaderContext.emitError(
  47. `\n Error compiling template:\n${pad(compiled.source)}\n` +
  48. compiled.errors.map(e => ` - ${e}`).join('\n') +
  49. '\n'
  50. )
  51. }
  52. const { code } = compiled
  53. // finish with ESM exports
  54. return code + `\nexport { render, staticRenderFns }`
  55. }
  56. function pad (source) {
  57. return source
  58. .split(/\r?\n/)
  59. .map(line => ` ${line}`)
  60. .join('\n')
  61. }