next
Version:
The React Framework
289 lines (288 loc) • 11.5 kB
JavaScript
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return loader;
}
});
const _CssSyntaxError = /*#__PURE__*/ _interop_require_default(require("./CssSyntaxError"));
const _Warning = /*#__PURE__*/ _interop_require_default(require("../../postcss-loader/src/Warning"));
const _stringifyrequest = require("../../../stringify-request");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const moduleRegExp = /\.module\.\w+$/i;
function getModulesOptions(rawOptions, loaderContext) {
const { resourcePath } = loaderContext;
if (typeof rawOptions.modules === 'undefined') {
const isModules = moduleRegExp.test(resourcePath);
if (!isModules) {
return false;
}
} else if (typeof rawOptions.modules === 'boolean' && rawOptions.modules === false) {
return false;
}
let modulesOptions = {
compileType: rawOptions.icss ? 'icss' : 'module',
auto: true,
mode: 'local',
exportGlobals: false,
localIdentName: '[hash:base64]',
localIdentContext: loaderContext.rootContext,
localIdentHashPrefix: '',
// eslint-disable-next-line no-undefined
localIdentRegExp: undefined,
namedExport: false,
exportLocalsConvention: 'asIs',
exportOnlyLocals: false
};
if (typeof rawOptions.modules === 'boolean' || typeof rawOptions.modules === 'string') {
modulesOptions.mode = typeof rawOptions.modules === 'string' ? rawOptions.modules : 'local';
} else {
if (rawOptions.modules) {
if (typeof rawOptions.modules.auto === 'boolean') {
const isModules = rawOptions.modules.auto && moduleRegExp.test(resourcePath);
if (!isModules) {
return false;
}
} else if (rawOptions.modules.auto instanceof RegExp) {
const isModules = rawOptions.modules.auto.test(resourcePath);
if (!isModules) {
return false;
}
} else if (typeof rawOptions.modules.auto === 'function') {
const isModule = rawOptions.modules.auto(resourcePath);
if (!isModule) {
return false;
}
}
if (rawOptions.modules.namedExport === true && typeof rawOptions.modules.exportLocalsConvention === 'undefined') {
modulesOptions.exportLocalsConvention = 'camelCaseOnly';
}
}
modulesOptions = {
...modulesOptions,
...rawOptions.modules || {}
};
}
if (typeof modulesOptions.mode === 'function') {
modulesOptions.mode = modulesOptions.mode(loaderContext.resourcePath);
}
if (modulesOptions.namedExport === true) {
if (rawOptions.esModule === false) {
throw Object.defineProperty(new Error('The "modules.namedExport" option requires the "esModules" option to be enabled'), "__NEXT_ERROR_CODE", {
value: "E103",
enumerable: false,
configurable: true
});
}
if (modulesOptions.exportLocalsConvention !== 'camelCaseOnly') {
throw Object.defineProperty(new Error('The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly"'), "__NEXT_ERROR_CODE", {
value: "E23",
enumerable: false,
configurable: true
});
}
}
return modulesOptions;
}
function normalizeOptions(rawOptions, loaderContext) {
if (rawOptions.icss) {
loaderContext.emitWarning(Object.defineProperty(new Error('The "icss" option is deprecated, use "modules.compileType: "icss"" instead'), "__NEXT_ERROR_CODE", {
value: "E476",
enumerable: false,
configurable: true
}));
}
const modulesOptions = getModulesOptions(rawOptions, loaderContext);
return {
url: typeof rawOptions.url === 'undefined' ? true : rawOptions.url,
import: typeof rawOptions.import === 'undefined' ? true : rawOptions.import,
modules: modulesOptions,
// TODO remove in the next major release
icss: typeof rawOptions.icss === 'undefined' ? false : rawOptions.icss,
sourceMap: typeof rawOptions.sourceMap === 'boolean' ? rawOptions.sourceMap : loaderContext.sourceMap,
importLoaders: typeof rawOptions.importLoaders === 'string' ? parseInt(rawOptions.importLoaders, 10) : rawOptions.importLoaders,
esModule: typeof rawOptions.esModule === 'undefined' ? true : rawOptions.esModule,
fontLoader: rawOptions.fontLoader
};
}
async function loader(content, map, meta) {
const rawOptions = this.getOptions();
const plugins = [];
const callback = this.async();
const loaderSpan = this.currentTraceSpan.traceChild('css-loader');
loaderSpan.traceAsyncFn(async ()=>{
let options;
try {
options = normalizeOptions(rawOptions, this);
} catch (error) {
throw error;
}
const { postcss } = await rawOptions.postcss();
const { shouldUseModulesPlugins, shouldUseImportPlugin, shouldUseURLPlugin, shouldUseIcssPlugin, getPreRequester, getExportCode, getFilter, getImportCode, getModuleCode, getModulesPlugins, normalizeSourceMap, sort } = require('./utils');
const { icssParser, importParser, urlParser } = require('./plugins');
const replacements = [];
// if it's a font loader next-font-loader will have exports that should be exported as is
const exports1 = options.fontLoader ? meta.exports : [];
if (shouldUseModulesPlugins(options)) {
plugins.push(...getModulesPlugins(options, this, meta));
}
const importPluginImports = [];
const importPluginApi = [];
if (shouldUseImportPlugin(options)) {
const resolver = this.getResolve({
conditionNames: [
'style'
],
extensions: [
'.css'
],
mainFields: [
'css',
'style',
'main',
'...'
],
mainFiles: [
'index',
'...'
],
restrictions: [
/\.css$/i
]
});
plugins.push(importParser({
imports: importPluginImports,
api: importPluginApi,
context: this.context,
rootContext: this.rootContext,
filter: getFilter(options.import, this.resourcePath),
resolver,
urlHandler: (url)=>(0, _stringifyrequest.stringifyRequest)(this, getPreRequester(this)(options.importLoaders) + url)
}));
}
const urlPluginImports = [];
if (shouldUseURLPlugin(options)) {
const urlResolver = this.getResolve({
conditionNames: [
'asset'
],
mainFields: [
'asset'
],
mainFiles: [],
extensions: []
});
plugins.push(urlParser({
imports: urlPluginImports,
replacements,
context: this.context,
rootContext: this.rootContext,
filter: getFilter(options.url, this.resourcePath),
resolver: urlResolver,
urlHandler: (url)=>(0, _stringifyrequest.stringifyRequest)(this, url)
}));
}
const icssPluginImports = [];
const icssPluginApi = [];
if (shouldUseIcssPlugin(options)) {
const icssResolver = this.getResolve({
conditionNames: [
'style'
],
extensions: [],
mainFields: [
'css',
'style',
'main',
'...'
],
mainFiles: [
'index',
'...'
]
});
plugins.push(icssParser({
imports: icssPluginImports,
api: icssPluginApi,
replacements,
exports: exports1,
context: this.context,
rootContext: this.rootContext,
resolver: icssResolver,
urlHandler: (url)=>(0, _stringifyrequest.stringifyRequest)(this, getPreRequester(this)(options.importLoaders) + url)
}));
}
// Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
if (meta) {
const { ast } = meta;
if (ast && ast.type === 'postcss') {
// eslint-disable-next-line no-param-reassign
content = ast.root;
loaderSpan.setAttribute('astUsed', 'true');
}
}
const { resourcePath } = this;
let result;
try {
result = await postcss(plugins).process(content, {
from: resourcePath,
to: resourcePath,
map: options.sourceMap ? {
prev: map ? normalizeSourceMap(map, resourcePath) : null,
inline: false,
annotation: false
} : false
});
} catch (error) {
if (error.file) {
this.addDependency(error.file);
}
throw error.name === 'CssSyntaxError' ? Object.defineProperty(new _CssSyntaxError.default(error), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
}) : error;
}
for (const warning of result.warnings()){
this.emitWarning(Object.defineProperty(new _Warning.default(warning), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
}));
}
const imports = [
...icssPluginImports.sort(sort),
...importPluginImports.sort(sort),
...urlPluginImports.sort(sort)
];
const api = [
...importPluginApi.sort(sort),
...icssPluginApi.sort(sort)
];
if (options.modules.exportOnlyLocals !== true) {
imports.unshift({
importName: '___CSS_LOADER_API_IMPORT___',
url: (0, _stringifyrequest.stringifyRequest)(this, require.resolve('./runtime/api'))
});
}
const importCode = getImportCode(imports, options);
const moduleCode = getModuleCode(result, api, replacements, options, this);
const exportCode = getExportCode(exports1, replacements, options);
return `${importCode}${moduleCode}${exportCode}`;
}).then((code)=>{
callback(null, code);
}, (err)=>{
callback(err);
});
}
//# sourceMappingURL=index.js.map