draft: refactor project so it sits on top of a standalone app
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
class SassError extends Error {
|
||||
constructor(sassError, resourcePath) {
|
||||
super();
|
||||
this.name = 'SassError';
|
||||
this.originalSassError = sassError;
|
||||
this.loc = {
|
||||
line: sassError.line,
|
||||
column: sassError.column
|
||||
}; // Keep original error if `sassError.formatted` is unavailable
|
||||
|
||||
this.message = `${this.name}: ${this.originalSassError.message}`;
|
||||
|
||||
if (this.originalSassError.formatted) {
|
||||
this.message = `${this.name}: ${this.originalSassError.formatted.replace(/^Error: /, '').replace(/(\s*)stdin(\s*)/, `$1${resourcePath}$2`)}`; // Instruct webpack to hide the JS stack from the console.
|
||||
// Usually you're only interested in the SASS stack in this case.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
this.hideStack = true;
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var _default = SassError;
|
||||
exports.default = _default;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const loader = require('./index');
|
||||
|
||||
module.exports = loader.default;
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
function getDefaultSassImplementation() {
|
||||
let sassImplPkg = 'node-sass';
|
||||
|
||||
try {
|
||||
require.resolve('node-sass');
|
||||
} catch (error) {
|
||||
try {
|
||||
require.resolve('sass');
|
||||
|
||||
sassImplPkg = 'sass';
|
||||
} catch (ignoreError) {
|
||||
sassImplPkg = 'node-sass';
|
||||
}
|
||||
} // eslint-disable-next-line import/no-dynamic-require, global-require
|
||||
|
||||
|
||||
return require(sassImplPkg);
|
||||
}
|
||||
|
||||
var _default = getDefaultSassImplementation;
|
||||
exports.default = _default;
|
||||
Generated
Vendored
+39
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _neoAsync = _interopRequireDefault(require("neo-async"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
let nodeSassJobQueue = null;
|
||||
/**
|
||||
* Verifies that the implementation and version of Sass is supported by this loader.
|
||||
*
|
||||
* @param {Object} implementation
|
||||
* @returns {Function}
|
||||
*/
|
||||
|
||||
function getRenderFunctionFromSassImplementation(implementation) {
|
||||
const isDartSass = implementation.info.includes('dart-sass');
|
||||
|
||||
if (isDartSass) {
|
||||
return implementation.render.bind(implementation);
|
||||
} // There is an issue with node-sass when async custom importers are used
|
||||
// See https://github.com/sass/node-sass/issues/857#issuecomment-93594360
|
||||
// We need to use a job queue to make sure that one thread is always available to the UV lib
|
||||
|
||||
|
||||
if (nodeSassJobQueue === null) {
|
||||
const threadPoolSize = Number(process.env.UV_THREADPOOL_SIZE || 4);
|
||||
nodeSassJobQueue = _neoAsync.default.queue(implementation.render.bind(implementation), threadPoolSize - 1);
|
||||
}
|
||||
|
||||
return nodeSassJobQueue.push.bind(nodeSassJobQueue);
|
||||
}
|
||||
|
||||
var _default = getRenderFunctionFromSassImplementation;
|
||||
exports.default = _default;
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _semver = _interopRequireDefault(require("semver"));
|
||||
|
||||
var _getDefaultSassImplementation = _interopRequireDefault(require("./getDefaultSassImplementation"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function getSassImplementation(implementation) {
|
||||
let resolvedImplementation = implementation;
|
||||
|
||||
if (!resolvedImplementation) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
resolvedImplementation = (0, _getDefaultSassImplementation.default)();
|
||||
}
|
||||
|
||||
const {
|
||||
info
|
||||
} = resolvedImplementation;
|
||||
|
||||
if (!info) {
|
||||
throw new Error('Unknown Sass implementation.');
|
||||
}
|
||||
|
||||
const infoParts = info.split('\t');
|
||||
|
||||
if (infoParts.length < 2) {
|
||||
throw new Error(`Unknown Sass implementation "${info}".`);
|
||||
}
|
||||
|
||||
const [implementationName, version] = infoParts;
|
||||
|
||||
if (implementationName === 'dart-sass') {
|
||||
if (!_semver.default.satisfies(version, '^1.3.0')) {
|
||||
throw new Error(`Dart Sass version ${version} is incompatible with ^1.3.0.`);
|
||||
}
|
||||
|
||||
return resolvedImplementation;
|
||||
} else if (implementationName === 'node-sass') {
|
||||
if (!_semver.default.satisfies(version, '^4.0.0')) {
|
||||
throw new Error(`Node Sass version ${version} is incompatible with ^4.0.0.`);
|
||||
}
|
||||
|
||||
return resolvedImplementation;
|
||||
}
|
||||
|
||||
throw new Error(`Unknown Sass implementation "${implementationName}".`);
|
||||
}
|
||||
|
||||
var _default = getSassImplementation;
|
||||
exports.default = _default;
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _os = _interopRequireDefault(require("os"));
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _cloneDeep = _interopRequireDefault(require("clone-deep"));
|
||||
|
||||
var _proxyCustomImporters = _interopRequireDefault(require("./proxyCustomImporters"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function isProductionLikeMode(loaderContext) {
|
||||
return loaderContext.mode === 'production' || !loaderContext.mode || loaderContext.minimize;
|
||||
}
|
||||
/**
|
||||
* Derives the sass options from the loader context and normalizes its values with sane defaults.
|
||||
*
|
||||
* @param {object} loaderContext
|
||||
* @param {object} loaderOptions
|
||||
* @param {string} content
|
||||
* @param {object} implementation
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
|
||||
function getSassOptions(loaderContext, loaderOptions, content, implementation) {
|
||||
const options = (0, _cloneDeep.default)(loaderOptions.sassOptions ? typeof loaderOptions.sassOptions === 'function' ? loaderOptions.sassOptions(loaderContext) || {} : loaderOptions.sassOptions : {});
|
||||
const isDartSass = implementation.info.includes('dart-sass');
|
||||
|
||||
if (isDartSass) {
|
||||
const shouldTryToResolveFibers = !options.fiber && options.fiber !== false;
|
||||
|
||||
if (shouldTryToResolveFibers) {
|
||||
let fibers;
|
||||
|
||||
try {
|
||||
fibers = require.resolve('fibers');
|
||||
} catch (_error) {// Nothing
|
||||
}
|
||||
|
||||
if (fibers) {
|
||||
// eslint-disable-next-line global-require, import/no-dynamic-require
|
||||
options.fiber = require(fibers);
|
||||
}
|
||||
} else if (options.fiber === false) {
|
||||
// Don't pass the `fiber` option for `sass` (`Dart Sass`)
|
||||
delete options.fiber;
|
||||
}
|
||||
} else {
|
||||
// Don't pass the `fiber` option for `node-sass`
|
||||
delete options.fiber;
|
||||
}
|
||||
|
||||
options.data = loaderOptions.prependData ? typeof loaderOptions.prependData === 'function' ? loaderOptions.prependData(loaderContext) + _os.default.EOL + content : loaderOptions.prependData + _os.default.EOL + content : content; // opt.outputStyle
|
||||
|
||||
if (!options.outputStyle && isProductionLikeMode(loaderContext)) {
|
||||
options.outputStyle = 'compressed';
|
||||
}
|
||||
|
||||
const useSourceMap = typeof loaderOptions.sourceMap === 'boolean' ? loaderOptions.sourceMap : loaderContext.sourceMap; // opt.sourceMap
|
||||
// Not using the `this.sourceMap` flag because css source maps are different
|
||||
// @see https://github.com/webpack/css-loader/pull/40
|
||||
|
||||
if (useSourceMap) {
|
||||
// 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.default.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;
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
resourcePath
|
||||
} = loaderContext;
|
||||
|
||||
const ext = _path.default.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 ? (0, _proxyCustomImporters.default)(options.importer, resourcePath) : [];
|
||||
options.includePaths = (options.includePaths || []).concat(_path.default.dirname(resourcePath));
|
||||
return options;
|
||||
}
|
||||
|
||||
var _default = getSassOptions;
|
||||
exports.default = _default;
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _loaderUtils = _interopRequireDefault(require("loader-utils"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
// Examples:
|
||||
// - ~package
|
||||
// - ~package/
|
||||
// - ~@org
|
||||
// - ~@org/
|
||||
// - ~@org/package
|
||||
// - ~@org/package/
|
||||
const matchModuleImport = /^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
|
||||
/**
|
||||
* When libsass tries to resolve an import, it uses a special algorithm.
|
||||
* Since the sass-loader uses webpack to resolve the modules, we need to simulate that algorithm. This function
|
||||
* returns an array of import paths to try. The last entry in the array is always the original url
|
||||
* to enable straight-forward webpack.config aliases.
|
||||
*
|
||||
* @param {string} url
|
||||
* @returns {Array<string>}
|
||||
*/
|
||||
|
||||
function importsToResolve(url) {
|
||||
const request = _loaderUtils.default.urlToRequest(url); // Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.
|
||||
// @see https://github.com/webpack-contrib/sass-loader/issues/167
|
||||
|
||||
|
||||
const ext = _path.default.extname(request).toLowerCase(); // In case there is module request, send this to webpack resolver
|
||||
|
||||
|
||||
if (matchModuleImport.test(url)) {
|
||||
return [request, url];
|
||||
} // Because @import is also defined in CSS, Sass needs a way of compiling plain CSS @imports without trying to import the files at compile time.
|
||||
// To accomplish this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will compile any @imports with the following characteristics to plain CSS imports:
|
||||
// - imports where the URL ends with .css.
|
||||
// - imports where the URL begins http:// or https://.
|
||||
// - imports where the URL is written as a url().
|
||||
// - imports that have media queries.
|
||||
//
|
||||
// The `node-sass` package sends `@import` ending on `.css` to importer, it is bug, so we skip resolve
|
||||
|
||||
|
||||
if (ext === '.css') {
|
||||
return [];
|
||||
}
|
||||
|
||||
const dirname = _path.default.dirname(request);
|
||||
|
||||
const basename = _path.default.basename(request); // In case there is file extension:
|
||||
//
|
||||
// 1. Try to resolve `_` file.
|
||||
// 2. Try to resolve file without `_`.
|
||||
// 3. Send a original url to webpack resolver, maybe it is alias.
|
||||
|
||||
|
||||
if (['.scss', '.sass'].includes(ext)) {
|
||||
return [`${dirname}/_${basename}`, `${dirname}/${basename}`, url];
|
||||
} // In case there is no file extension and filename starts with `_`:
|
||||
//
|
||||
// 1. Try to resolve files with `scss`, `sass` and `css` extensions.
|
||||
// 2. Try to resolve directory with `_index` or `index` filename.
|
||||
// 3. Send the original url to webpack resolver, maybe it's alias.
|
||||
|
||||
|
||||
if (basename.startsWith('_')) {
|
||||
return [`${request}.scss`, `${request}.sass`, `${request}.css`, request, url];
|
||||
} // In case there is no file extension and filename doesn't start with `_`:
|
||||
//
|
||||
// 1. Try to resolve file starts with `_` and with extensions
|
||||
// 2. Try to resolve file with extensions
|
||||
// 3. Try to resolve directory with `_index` or `index` filename.
|
||||
// 4. Send a original url to webpack resolver, maybe it is alias.
|
||||
|
||||
|
||||
return [`${dirname}/_${basename}.scss`, `${dirname}/_${basename}.sass`, `${dirname}/_${basename}.css`, `${request}.scss`, `${request}.sass`, `${request}.css`, request, url];
|
||||
}
|
||||
|
||||
var _default = importsToResolve;
|
||||
exports.default = _default;
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _schemaUtils = _interopRequireDefault(require("schema-utils"));
|
||||
|
||||
var _loaderUtils = require("loader-utils");
|
||||
|
||||
var _options = _interopRequireDefault(require("./options.json"));
|
||||
|
||||
var _getSassImplementation = _interopRequireDefault(require("./getSassImplementation"));
|
||||
|
||||
var _getSassOptions = _interopRequireDefault(require("./getSassOptions"));
|
||||
|
||||
var _webpackImporter = _interopRequireDefault(require("./webpackImporter"));
|
||||
|
||||
var _getRenderFunctionFromSassImplementation = _interopRequireDefault(require("./getRenderFunctionFromSassImplementation"));
|
||||
|
||||
var _SassError = _interopRequireDefault(require("./SassError"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
/**
|
||||
* The sass-loader makes node-sass and dart-sass available to webpack modules.
|
||||
*
|
||||
* @this {object}
|
||||
* @param {string} content
|
||||
*/
|
||||
function loader(content) {
|
||||
const options = (0, _loaderUtils.getOptions)(this) || {};
|
||||
(0, _schemaUtils.default)(_options.default, options, {
|
||||
name: 'Sass Loader',
|
||||
baseDataPath: 'options'
|
||||
});
|
||||
const implementation = (0, _getSassImplementation.default)(options.implementation);
|
||||
const callback = this.async();
|
||||
|
||||
const addNormalizedDependency = file => {
|
||||
// node-sass returns POSIX paths
|
||||
this.addDependency(_path.default.normalize(file));
|
||||
};
|
||||
|
||||
const sassOptions = (0, _getSassOptions.default)(this, options, content, implementation);
|
||||
const shouldUseWebpackImporter = typeof options.webpackImporter === 'boolean' ? options.webpackImporter : true;
|
||||
|
||||
if (shouldUseWebpackImporter) {
|
||||
const resolve = this.getResolve({
|
||||
mainFields: ['sass', 'style', 'main', '...'],
|
||||
mainFiles: ['_index', 'index', '...'],
|
||||
extensions: ['.scss', '.sass', '.css', '...']
|
||||
});
|
||||
sassOptions.importer.push((0, _webpackImporter.default)(this.resourcePath, resolve, addNormalizedDependency));
|
||||
} // Skip empty files, otherwise it will stop webpack, see issue #21
|
||||
|
||||
|
||||
if (sassOptions.data.trim() === '') {
|
||||
callback(null, '');
|
||||
return;
|
||||
}
|
||||
|
||||
const render = (0, _getRenderFunctionFromSassImplementation.default)(implementation);
|
||||
render(sassOptions, (error, result) => {
|
||||
if (error) {
|
||||
if (error.file) {
|
||||
addNormalizedDependency(error.file);
|
||||
}
|
||||
|
||||
callback(new _SassError.default(error, this.resourcePath));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.map && result.map !== '{}') {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
result.map = JSON.parse(result.map); // result.map.file is an optional property that provides the output filename.
|
||||
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
delete result.map.file; // One of the sources is 'stdin' according to dart-sass/node-sass because we've used the data input.
|
||||
// Now let's override that value with the correct relative path.
|
||||
// Since we specified options.sourceMap = path.join(process.cwd(), "/sass.map"); in getSassOptions,
|
||||
// we know that this path is relative to process.cwd(). This is how node-sass works.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
const stdinIndex = result.map.sources.findIndex(source => source.includes('stdin'));
|
||||
|
||||
if (stdinIndex !== -1) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
result.map.sources[stdinIndex] = _path.default.relative(process.cwd(), this.resourcePath);
|
||||
} // node-sass returns POSIX paths, that's why we need to transform them back to native paths.
|
||||
// This fixes an error on windows where the source-map module cannot resolve the source maps.
|
||||
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
||||
|
||||
result.map.sourceRoot = _path.default.normalize(result.map.sourceRoot); // eslint-disable-next-line no-param-reassign
|
||||
|
||||
result.map.sources = result.map.sources.map(_path.default.normalize);
|
||||
} else {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
result.map = null;
|
||||
}
|
||||
|
||||
result.stats.includedFiles.forEach(addNormalizedDependency);
|
||||
callback(null, result.css.toString(), result.map);
|
||||
});
|
||||
}
|
||||
|
||||
var _default = loader;
|
||||
exports.default = _default;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"implementation": {
|
||||
"description": "The implementation of the sass to be used (https://github.com/webpack-contrib/sass-loader#implementation).",
|
||||
"type": "object"
|
||||
},
|
||||
"sassOptions": {
|
||||
"description": "Options for `node-sass` or `sass` (`Dart Sass`) implementation. (https://github.com/webpack-contrib/sass-loader#implementation).",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"prependData": {
|
||||
"description": "Prepends `Sass`/`SCSS` code before the actual entry file (https://github.com/webpack-contrib/sass-loader#prependdata).",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sourceMap": {
|
||||
"description": "Enables/Disables generation of source maps (https://github.com/webpack-contrib/sass-loader#sourcemap).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"webpackImporter": {
|
||||
"description": "Enables/Disables default `webpack` importer (https://github.com/webpack-contrib/sass-loader#webpackimporter).",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
/**
|
||||
* Creates new custom importers that use the given `resourcePath` if libsass calls the custom importer with `prev`
|
||||
* being 'stdin'.
|
||||
*
|
||||
* Why do we need this? We have to use the `data` option of node-sass in order to compile our sass because
|
||||
* the `resourcePath` might not be an actual file on disk. When using the `data` option, libsass uses the string
|
||||
* 'stdin' instead of a filename.
|
||||
*
|
||||
* We have to fix this behavior in order to provide a consistent experience to the webpack user.
|
||||
*
|
||||
* @param {Function|Array<Function>} importer
|
||||
* @param {string} resourcePath
|
||||
* @returns {Array<Function>}
|
||||
*/
|
||||
function proxyCustomImporters(importer, resourcePath) {
|
||||
return [].concat(importer).map( // eslint-disable-next-line no-shadow
|
||||
importer => function customImporter() {
|
||||
return importer.apply(this, // eslint-disable-next-line prefer-rest-params
|
||||
Array.from(arguments).map((arg, i) => i === 1 && arg === 'stdin' ? resourcePath : arg));
|
||||
});
|
||||
}
|
||||
|
||||
var _default = proxyCustomImporters;
|
||||
exports.default = _default;
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _importsToResolve = _interopRequireDefault(require("./importsToResolve"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
/**
|
||||
* @name PromisedResolve
|
||||
* @type {Function}
|
||||
* @param {string} dir
|
||||
* @param {string} request
|
||||
* @returns Promise
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Importer
|
||||
* @type {Function}
|
||||
* @param {string} url
|
||||
* @param {string} prev
|
||||
* @param {Function<Error, string>} done
|
||||
*/
|
||||
const matchCss = /\.css$/i;
|
||||
/**
|
||||
* Returns an importer that uses webpack's resolving algorithm.
|
||||
*
|
||||
* It's important that the returned function has the correct number of arguments
|
||||
* (based on whether the call is sync or async) because otherwise node-sass doesn't exit.
|
||||
*
|
||||
* @param {string} resourcePath
|
||||
* @param {PromisedResolve} resolve
|
||||
* @param {Function<string>} addNormalizedDependency
|
||||
* @returns {Importer}
|
||||
*/
|
||||
|
||||
function webpackImporter(resourcePath, resolve, addNormalizedDependency) {
|
||||
function dirContextFrom(fileContext) {
|
||||
return _path.default.dirname( // The first file is 'stdin' when we're using the data option
|
||||
fileContext === 'stdin' ? resourcePath : fileContext);
|
||||
} // eslint-disable-next-line no-shadow
|
||||
|
||||
|
||||
function startResolving(dir, importsToResolve) {
|
||||
return importsToResolve.length === 0 ? Promise.reject() : resolve(dir, importsToResolve[0]).then(resolvedFile => {
|
||||
// Add the resolvedFilename as dependency. Although we're also using stats.includedFiles, this might come
|
||||
// in handy when an error occurs. In this case, we don't get stats.includedFiles from node-sass.
|
||||
addNormalizedDependency(resolvedFile);
|
||||
return {
|
||||
// By removing the CSS file extension, we trigger node-sass to include the CSS file instead of just linking it.
|
||||
file: resolvedFile.replace(matchCss, '')
|
||||
};
|
||||
}, () => {
|
||||
const [, ...tailResult] = importsToResolve;
|
||||
return startResolving(dir, tailResult);
|
||||
});
|
||||
}
|
||||
|
||||
return (url, prev, done) => {
|
||||
startResolving(dirContextFrom(prev), (0, _importsToResolve.default)(url)) // Catch all resolving errors, return the original file and pass responsibility back to other custom importers
|
||||
.catch(() => {
|
||||
return {
|
||||
file: url
|
||||
};
|
||||
}).then(done);
|
||||
};
|
||||
}
|
||||
|
||||
var _default = webpackImporter;
|
||||
exports.default = _default;
|
||||
Reference in New Issue
Block a user