index.js 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. module.exports = function () {}
  10. module.exports.pitch = function (remainingRequest) {
  11. if (this.cacheable) this.cacheable()
  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 request = loaderUtils.stringifyRequest(this, '!!' + remainingRequest)
  17. var id = JSON.stringify(hash(request + path.relative(__dirname, this.resourcePath)))
  18. var options = loaderUtils.getOptions(this) || {}
  19. // direct css import from js --> direct, or manually call `styles.__inject__(ssrContext)` with `manualInject` option
  20. // css import from vue file --> component lifecycle linked
  21. // style embedded in vue file --> component lifecycle linked
  22. var isVue = /"vue":true/.test(remainingRequest) || options.manualInject
  23. var shared = [
  24. '// style-loader: Adds some css to the DOM by adding a <style> tag',
  25. '',
  26. '// load the styles',
  27. 'var content = require(' + request + ');',
  28. // content list format is [id, css, media, sourceMap]
  29. "if(typeof content === 'string') content = [[module.id, content, '']];",
  30. 'if(content.locals) module.exports = content.locals;'
  31. ]
  32. if (!isServer) {
  33. // on the client: dynamic inject + hot-reload
  34. var code = [
  35. '// add the styles to the DOM',
  36. 'var update = require(' + addStylesClientPath + ')(' + id + ', content, ' + isProduction + ', ' + JSON.stringify(options) + ');'
  37. ]
  38. if (!isProduction) {
  39. code = code.concat([
  40. '// Hot Module Replacement',
  41. 'if(module.hot) {',
  42. ' // When the styles change, update the <style> tags',
  43. ' if(!content.locals) {',
  44. ' module.hot.accept(' + request + ', function() {',
  45. ' var newContent = require(' + request + ');',
  46. " if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];",
  47. ' update(newContent);',
  48. ' });',
  49. ' }',
  50. ' // When the module is disposed, remove the <style> tags',
  51. ' module.hot.dispose(function() { update(); });',
  52. '}'
  53. ])
  54. }
  55. return shared.concat(code).join('\n')
  56. } else {
  57. // on the server: attach to Vue SSR context
  58. if (isVue) {
  59. // inside *.vue file: expose a function so it can be called in
  60. // component's lifecycle hooks
  61. return shared.concat([
  62. '// add CSS to SSR context',
  63. 'var add = require(' + addStylesServerPath + ')',
  64. 'module.exports.__inject__ = function (context) {',
  65. ' add(' + id + ', content, ' + isProduction + ', context)',
  66. '};'
  67. ]).join('\n')
  68. } else {
  69. // normal import
  70. return shared.concat([
  71. 'require(' + addStylesServerPath + ')(' + id + ', content, ' + isProduction + ')'
  72. ]).join('\n')
  73. }
  74. }
  75. }