| "use strict"; |
| |
| const os = require("os"); |
| const utils = require("loader-utils"); |
| const cloneDeep = require("clone-deep"); |
| const path = require("path"); |
| const proxyCustomImporters = require("./proxyCustomImporters"); |
| |
| /** |
| * Derives the sass options from the loader context and normalizes its values with sane defaults. |
| * |
| * Please note: If loaderContext.query is an options object, it will be re-used across multiple invocations. |
| * That's why we must not modify the object directly. |
| * |
| * @param {LoaderContext} loaderContext |
| * @param {string} content |
| * @param {Function} webpackImporter |
| * @returns {Object} |
| */ |
| function normalizeOptions(loaderContext, content, webpackImporter) { |
| const options = cloneDeep(utils.getOptions(loaderContext)) || {}; |
| const resourcePath = loaderContext.resourcePath; |
| |
| options.data = options.data ? (options.data + os.EOL + content) : content; |
| |
| // opt.outputStyle |
| if (!options.outputStyle && loaderContext.minimize) { |
| options.outputStyle = "compressed"; |
| } |
| |
| // opt.sourceMap |
| // Not using the `this.sourceMap` flag because css source maps are different |
| // @see https://github.com/webpack/css-loader/pull/40 |
| if (options.sourceMap) { |
| // Deliberately overriding the sourceMap option here. |
| // node-sass won't produce source maps if the data option is used and options.sourceMap is not a string. |
| // In case it is a string, options.sourceMap should be a path where the source map is written. |
| // But since we're using the data option, the source map will not actually be written, but |
| // all paths in sourceMap.sources will be relative to that path. |
| // Pretty complicated... :( |
| options.sourceMap = path.join(process.cwd(), "/sass.map"); |
| if ("sourceMapRoot" in options === false) { |
| options.sourceMapRoot = process.cwd(); |
| } |
| if ("omitSourceMapUrl" in options === false) { |
| // The source map url doesn't make sense because we don't know the output path |
| // The css-loader will handle that for us |
| options.omitSourceMapUrl = true; |
| } |
| if ("sourceMapContents" in options === false) { |
| // If sourceMapContents option is not set, set it to true otherwise maps will be empty/null |
| // when exported by webpack-extract-text-plugin. |
| options.sourceMapContents = true; |
| } |
| } |
| |
| // indentedSyntax is a boolean flag. |
| const ext = path.extname(resourcePath); |
| |
| // If we are compiling sass and indentedSyntax isn't set, automatically set it. |
| if (ext && ext.toLowerCase() === ".sass" && "indentedSyntax" in options === false) { |
| options.indentedSyntax = true; |
| } else { |
| options.indentedSyntax = Boolean(options.indentedSyntax); |
| } |
| |
| // Allow passing custom importers to `node-sass`. Accepts `Function` or an array of `Function`s. |
| options.importer = options.importer ? proxyCustomImporters(options.importer, resourcePath) : []; |
| options.importer.push(webpackImporter); |
| |
| // `node-sass` uses `includePaths` to resolve `@import` paths. Append the currently processed file. |
| options.includePaths = options.includePaths || []; |
| options.includePaths.push(path.dirname(resourcePath)); |
| |
| return options; |
| } |
| |
| module.exports = normalizeOptions; |