normalizeOptions.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. "use strict";
  2. const os = require("os");
  3. const utils = require("loader-utils");
  4. const cloneDeep = require("clone-deep");
  5. const path = require("path");
  6. const proxyCustomImporters = require("./proxyCustomImporters");
  7. /**
  8. * Derives the sass options from the loader context and normalizes its values with sane defaults.
  9. *
  10. * Please note: If loaderContext.query is an options object, it will be re-used across multiple invocations.
  11. * That's why we must not modify the object directly.
  12. *
  13. * @param {LoaderContext} loaderContext
  14. * @param {string} content
  15. * @param {Function} webpackImporter
  16. * @returns {Object}
  17. */
  18. function normalizeOptions(loaderContext, content, webpackImporter) {
  19. const options = cloneDeep(utils.getOptions(loaderContext)) || {};
  20. const resourcePath = loaderContext.resourcePath;
  21. options.data = options.data ? (options.data + os.EOL + content) : content;
  22. // opt.outputStyle
  23. if (!options.outputStyle && loaderContext.minimize) {
  24. options.outputStyle = "compressed";
  25. }
  26. // opt.sourceMap
  27. // Not using the `this.sourceMap` flag because css source maps are different
  28. // @see https://github.com/webpack/css-loader/pull/40
  29. if (options.sourceMap) {
  30. // Deliberately overriding the sourceMap option here.
  31. // node-sass won't produce source maps if the data option is used and options.sourceMap is not a string.
  32. // In case it is a string, options.sourceMap should be a path where the source map is written.
  33. // But since we're using the data option, the source map will not actually be written, but
  34. // all paths in sourceMap.sources will be relative to that path.
  35. // Pretty complicated... :(
  36. options.sourceMap = path.join(process.cwd(), "/sass.map");
  37. if ("sourceMapRoot" in options === false) {
  38. options.sourceMapRoot = process.cwd();
  39. }
  40. if ("omitSourceMapUrl" in options === false) {
  41. // The source map url doesn't make sense because we don't know the output path
  42. // The css-loader will handle that for us
  43. options.omitSourceMapUrl = true;
  44. }
  45. if ("sourceMapContents" in options === false) {
  46. // If sourceMapContents option is not set, set it to true otherwise maps will be empty/null
  47. // when exported by webpack-extract-text-plugin.
  48. options.sourceMapContents = true;
  49. }
  50. }
  51. // indentedSyntax is a boolean flag.
  52. const ext = path.extname(resourcePath);
  53. // If we are compiling sass and indentedSyntax isn't set, automatically set it.
  54. if (ext && ext.toLowerCase() === ".sass" && "indentedSyntax" in options === false) {
  55. options.indentedSyntax = true;
  56. } else {
  57. options.indentedSyntax = Boolean(options.indentedSyntax);
  58. }
  59. // Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s.
  60. options.importer = options.importer ? proxyCustomImporters(options.importer, resourcePath) : [];
  61. options.importer.push(webpackImporter);
  62. // `node-sass` uses `includePaths` to resolve `@import` paths. Append the currently processed file.
  63. options.includePaths = options.includePaths || [];
  64. options.includePaths.push(path.dirname(resourcePath));
  65. return options;
  66. }
  67. module.exports = normalizeOptions;