index.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. Modified by Evan You @yyx990803
  5. */
  6. var loaderUtils = require('loader-utils')
  7. var path = require('path')
  8. var hash = require('hash-sum')
  9. var qs = require('querystring')
  10. module.exports = function () {}
  11. module.exports.pitch = function (remainingRequest) {
  12. var isServer = this.target === 'node'
  13. var isProduction = this.minimize || process.env.NODE_ENV === 'production'
  14. var addStylesClientPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesClient.js'))
  15. var addStylesServerPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesServer.js'))
  16. var addStylesShadowPath = loaderUtils.stringifyRequest(this, '!' + path.join(__dirname, 'lib/addStylesShadow.js'))
  17. var request = loaderUtils.stringifyRequest(this, '!!' + remainingRequest)
  18. var relPath = path.relative(__dirname, this.resourcePath).replace(/\\/g, '/')
  19. var id = JSON.stringify(hash(request + relPath))
  20. var options = loaderUtils.getOptions(this) || {}
  21. // direct css import from js --> direct, or manually call `styles.__inject__(ssrContext)` with `manualInject` option
  22. // css import from vue file --> component lifecycle linked
  23. // style embedded in vue file --> component lifecycle linked
  24. var isVue = (
  25. /"vue":true/.test(remainingRequest) ||
  26. options.manualInject ||
  27. qs.parse(this.resourceQuery.slice(1)).vue != null
  28. )
  29. var shared = [
  30. '// style-loader: Adds some css to the DOM by adding a <style> tag',
  31. '',
  32. '// load the styles',
  33. 'var content = require(' + request + ');',
  34. // get default export if list is an ES Module (CSS Loader v4+)
  35. "if(content.__esModule) content = content.default;",
  36. // content list format is [id, css, media, sourceMap]
  37. "if(typeof content === 'string') content = [[module.id, content, '']];",
  38. 'if(content.locals) module.exports = content.locals;'
  39. ]
  40. // shadowMode is enabled in vue-cli with vue build --target web-component.
  41. // exposes the same __inject__ method like SSR
  42. if (options.shadowMode) {
  43. return shared.concat([
  44. '// add CSS to Shadow Root',
  45. 'var add = require(' + addStylesShadowPath + ').default',
  46. 'module.exports.__inject__ = function (shadowRoot) {',
  47. ' add(' + id + ', content, shadowRoot)',
  48. '};'
  49. ]).join('\n')
  50. } else if (!isServer) {
  51. // on the client: dynamic inject + hot-reload
  52. var code = [
  53. '// add the styles to the DOM',
  54. 'var add = require(' + addStylesClientPath + ').default',
  55. 'var update = add(' + id + ', content, ' + isProduction + ', ' + JSON.stringify(options) + ');'
  56. ]
  57. if (!isProduction) {
  58. code = code.concat([
  59. '// Hot Module Replacement',
  60. 'if(module.hot) {',
  61. ' // When the styles change, update the <style> tags',
  62. ' if(!content.locals) {',
  63. ' module.hot.accept(' + request + ', function() {',
  64. ' var newContent = require(' + request + ');',
  65. ' if(newContent.__esModule) newContent = newContent.default;',
  66. " if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];",
  67. ' update(newContent);',
  68. ' });',
  69. ' }',
  70. ' // When the module is disposed, remove the <style> tags',
  71. ' module.hot.dispose(function() { update(); });',
  72. '}'
  73. ])
  74. }
  75. return shared.concat(code).join('\n')
  76. } else {
  77. // on the server: attach to Vue SSR context
  78. if (isVue) {
  79. // inside *.vue file: expose a function so it can be called in
  80. // component's lifecycle hooks
  81. return shared.concat([
  82. '// add CSS to SSR context',
  83. 'var add = require(' + addStylesServerPath + ').default',
  84. 'module.exports.__inject__ = function (context) {',
  85. ' add(' + id + ', content, ' + isProduction + ', context)',
  86. '};'
  87. ]).join('\n')
  88. } else {
  89. // normal import
  90. return shared.concat([
  91. 'require(' + addStylesServerPath + ').default(' + id + ', content, ' + isProduction + ')'
  92. ]).join('\n')
  93. }
  94. }
  95. }