You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
3.8 KiB

4 years ago
  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. // content list format is [id, css, media, sourceMap]
  35. "if(typeof content === 'string') content = [[module.id, content, '']];",
  36. 'if(content.locals) module.exports = content.locals;'
  37. ]
  38. // shadowMode is enabled in vue-cli with vue build --target web-component.
  39. // exposes the same __inject__ method like SSR
  40. if (options.shadowMode) {
  41. return shared.concat([
  42. '// add CSS to Shadow Root',
  43. 'var add = require(' + addStylesShadowPath + ').default',
  44. 'module.exports.__inject__ = function (shadowRoot) {',
  45. ' add(' + id + ', content, shadowRoot)',
  46. '};'
  47. ]).join('\n')
  48. } else if (!isServer) {
  49. // on the client: dynamic inject + hot-reload
  50. var code = [
  51. '// add the styles to the DOM',
  52. 'var add = require(' + addStylesClientPath + ').default',
  53. 'var update = add(' + id + ', content, ' + isProduction + ', ' + JSON.stringify(options) + ');'
  54. ]
  55. if (!isProduction) {
  56. code = code.concat([
  57. '// Hot Module Replacement',
  58. 'if(module.hot) {',
  59. ' // When the styles change, update the <style> tags',
  60. ' if(!content.locals) {',
  61. ' module.hot.accept(' + request + ', function() {',
  62. ' var newContent = require(' + request + ');',
  63. " if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];",
  64. ' update(newContent);',
  65. ' });',
  66. ' }',
  67. ' // When the module is disposed, remove the <style> tags',
  68. ' module.hot.dispose(function() { update(); });',
  69. '}'
  70. ])
  71. }
  72. return shared.concat(code).join('\n')
  73. } else {
  74. // on the server: attach to Vue SSR context
  75. if (isVue) {
  76. // inside *.vue file: expose a function so it can be called in
  77. // component's lifecycle hooks
  78. return shared.concat([
  79. '// add CSS to SSR context',
  80. 'var add = require(' + addStylesServerPath + ').default',
  81. 'module.exports.__inject__ = function (context) {',
  82. ' add(' + id + ', content, ' + isProduction + ', context)',
  83. '};'
  84. ]).join('\n')
  85. } else {
  86. // normal import
  87. return shared.concat([
  88. 'require(' + addStylesServerPath + ').default(' + id + ', content, ' + isProduction + ')'
  89. ]).join('\n')
  90. }
  91. }
  92. }