123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.getImports = getImports;
- exports.renderImports = renderImports;
- exports.sourceHasUseStrict = sourceHasUseStrict;
- var _path = _interopRequireDefault(require("path"));
- var _stripComments = _interopRequireDefault(require("strip-comments"));
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
- const matchRelativePath = /^\.\.?[/\\]/;
- function isAbsolutePath(str) {
- return _path.default.posix.isAbsolute(str) || _path.default.win32.isAbsolute(str);
- }
- function isRelativePath(str) {
- return matchRelativePath.test(str);
- } // TODO simplify for the next major release
- function stringifyRequest(loaderContext, request) {
- if (typeof loaderContext.utils !== "undefined" && typeof loaderContext.utils.contextify === "function") {
- return JSON.stringify(loaderContext.utils.contextify(loaderContext.context, request));
- }
- const splitted = request.split("!");
- const {
- context
- } = loaderContext;
- return JSON.stringify(splitted.map(part => {
- // First, separate singlePath from query, because the query might contain paths again
- const splittedPart = part.match(/^(.*?)(\?.*)/);
- const query = splittedPart ? splittedPart[2] : "";
- let singlePath = splittedPart ? splittedPart[1] : part;
- if (isAbsolutePath(singlePath) && context) {
- singlePath = _path.default.relative(context, singlePath);
- if (isAbsolutePath(singlePath)) {
- // If singlePath still matches an absolute path, singlePath was on a different drive than context.
- // In this case, we leave the path platform-specific without replacing any separators.
- // @see https://github.com/webpack/loader-utils/pull/14
- return singlePath + query;
- }
- if (isRelativePath(singlePath) === false) {
- // Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules).
- singlePath = `./${singlePath}`;
- }
- }
- return singlePath.replace(/\\/g, "/") + query;
- }).join("!"));
- }
- function forError(item) {
- return typeof item === "string" ? item : `\n${JSON.stringify(item, null, " ")}\n`;
- }
- function sourceHasUseStrict(source) {
- const str = (0, _stripComments.default)(source).trim();
- return str.startsWith("'use strict'") || str.startsWith('"use strict"');
- }
- function splitCommand(command) {
- const result = command.split("|").map(item => item.split(" ")).reduce((acc, val) => acc.concat(val), []);
- for (const item of result) {
- if (!item) {
- throw new Error(`Invalid command "${item}" in "${command}" for imports. There must be only one separator: " ", or "|"`);
- }
- }
- return result;
- }
- function resolveImports(type, item) {
- const defaultSyntax = type === "module" ? "default" : "single";
- let result;
- if (typeof item === "string") {
- const noWhitespaceItem = item.trim();
- if (noWhitespaceItem.length === 0) {
- throw new Error(`Invalid "${item}" value for import`);
- }
- const splittedItem = splitCommand(noWhitespaceItem);
- if (splittedItem.length > 4) {
- throw new Error(`Invalid "${item}" value for import`);
- }
- if (splittedItem.length === 1) {
- result = {
- syntax: defaultSyntax,
- moduleName: splittedItem[0],
- name: splittedItem[0],
- // eslint-disable-next-line no-undefined
- alias: undefined
- };
- } else {
- result = {
- syntax: splittedItem[0],
- moduleName: splittedItem[1],
- name: splittedItem[2],
- // eslint-disable-next-line no-undefined
- alias: splittedItem[3] ? splittedItem[3] : undefined
- };
- }
- } else {
- result = {
- syntax: defaultSyntax,
- ...item
- };
- }
- if (result.syntax === defaultSyntax && typeof result.name === "undefined") {
- result.name = result.moduleName;
- }
- if (["default", "side-effects", "single", "pure"].includes(result.syntax) && typeof result.alias !== "undefined") {
- throw new Error(`The "${result.syntax}" syntax does not support "${result.alias}" alias in "${forError(item)}" value`);
- }
- if (["side-effects", "pure"].includes(result.syntax) && typeof result.name !== "undefined") {
- throw new Error(`The "${result.syntax}" syntax does not support "${result.name}" name in "${forError(item)}" value`);
- }
- if (["default", "namespace", "named", "side-effects"].includes(result.syntax) && type === "commonjs") {
- throw new Error(`The "${type}" type does not support the "${result.syntax}" syntax in "${forError(item)}" value`);
- }
- if (["single", "multiple", "pure"].includes(result.syntax) && type === "module") {
- throw new Error(`The "${type}" format does not support the "${result.syntax}" syntax in "${forError(item)}" value`);
- }
- if (["namespace", "named", "multiple"].includes(result.syntax) && typeof result.name === "undefined") {
- throw new Error(`The "${result.syntax}" syntax needs the "name" option in "${forError(item)}" value`);
- }
- return result;
- }
- function getIdentifiers(array) {
- return array.reduce((accumulator, item) => {
- if (typeof item.alias !== "undefined") {
- accumulator.push({
- type: "alias",
- value: item.alias
- });
- return accumulator;
- }
- if (typeof item.name !== "undefined") {
- accumulator.push({
- type: "name",
- value: item.name
- });
- }
- return accumulator;
- }, []);
- }
- function duplicateBy(array, key) {
- return array.filter((a, aIndex) => array.filter((b, bIndex) => b[key] === a[key] && aIndex !== bIndex).length > 0);
- }
- function getImports(type, imports) {
- let result;
- const importItems = typeof imports === "string" && imports.includes(",") ? imports.split(",") : imports;
- if (typeof importItems === "string") {
- result = [resolveImports(type, importItems)];
- } else {
- result = [].concat(importItems).map(item => resolveImports(type, item));
- }
- const identifiers = getIdentifiers(result);
- const duplicates = duplicateBy(identifiers, "value");
- if (duplicates.length > 0) {
- throw new Error(`Duplicate ${duplicates.map(identifier => `"${identifier.value}" (as "${identifier.type}")`).join(", ")} identifiers found in "\n${JSON.stringify(importItems, null, " ")}\n" value`);
- }
- const sortedResults = Object.create(null);
- for (const item of result) {
- const {
- moduleName
- } = item;
- if (!sortedResults[moduleName]) {
- sortedResults[moduleName] = [];
- }
- const {
- syntax,
- name,
- alias
- } = item;
- sortedResults[moduleName].push({
- syntax,
- name,
- alias
- });
- }
- return sortedResults;
- }
- function renderImports(loaderContext, type, moduleName, imports) {
- let code = "";
- if (type === "commonjs") {
- const pure = imports.filter(({
- syntax
- }) => syntax === "pure"); // Pure
- if (pure.length > 0) {
- pure.forEach((_, i) => {
- const needNewline = i < pure.length - 1 ? "\n" : "";
- code += `require(${stringifyRequest(loaderContext, moduleName)});${needNewline}`;
- });
- }
- const singleImports = imports.filter(({
- syntax
- }) => syntax === "single"); // Single
- if (singleImports.length > 0) {
- code += pure.length > 0 ? "\n" : "";
- singleImports.forEach((singleImport, i) => {
- const {
- name
- } = singleImport;
- const needNewline = i < singleImports.length - 1 ? "\n" : "";
- code += `var ${name} = require(${stringifyRequest(loaderContext, moduleName)});${needNewline}`;
- });
- }
- const multipleImports = imports.filter(({
- syntax
- }) => syntax === "multiple"); // Multiple
- if (multipleImports.length > 0) {
- code += pure.length > 0 || singleImports.length > 0 ? "\n" : "";
- code += `var { `;
- multipleImports.forEach((multipleImport, i) => {
- const needComma = i > 0 ? ", " : "";
- const {
- name,
- alias
- } = multipleImport;
- const separator = ": ";
- code += alias ? `${needComma}${name}${separator}${alias}` : `${needComma}${name}`;
- });
- code += ` } = require(${stringifyRequest(loaderContext, moduleName)});`;
- }
- return code;
- }
- const sideEffectsImports = imports.filter(({
- syntax
- }) => syntax === "side-effects"); // Side-effects
- if (sideEffectsImports.length > 0) {
- sideEffectsImports.forEach((_, i) => {
- const needNewline = i < sideEffectsImports.length - 1 ? "\n" : "";
- code += `import ${stringifyRequest(loaderContext, moduleName)};${needNewline}`;
- });
- return code;
- }
- const defaultImports = imports.filter(({
- syntax
- }) => syntax === "default");
- const namedImports = imports.filter(({
- syntax
- }) => syntax === "named");
- const namespaceImports = imports.filter(({
- syntax
- }) => syntax === "namespace"); // Default
- if (defaultImports.length > 0) {
- defaultImports.forEach((defaultImport, i) => {
- const {
- name
- } = defaultImport;
- const needNewline = i < defaultImports.length - 1 ? "\n" : "";
- code += `import ${name} from ${stringifyRequest(loaderContext, moduleName)};${needNewline}`;
- });
- } // Named
- if (namedImports.length > 0) {
- code += defaultImports.length > 0 ? "\n" : "";
- code += "import { ";
- namedImports.forEach((namedImport, i) => {
- const needComma = i > 0 ? ", " : "";
- const {
- name,
- alias
- } = namedImport;
- const separator = " as ";
- code += alias ? `${needComma}${name}${separator}${alias}` : `${needComma}${name}`;
- });
- code += ` } from ${stringifyRequest(loaderContext, moduleName)};`;
- } // Namespace
- if (namespaceImports.length > 0) {
- code += defaultImports.length > 0 || namedImports.length > 0 ? "\n" : "";
- namespaceImports.forEach((namespaceImport, i) => {
- const {
- name
- } = namespaceImport;
- const needNewline = i < namespaceImports.length - 1 ? "\n" : "";
- code += `import * as ${name} from ${stringifyRequest(loaderContext, moduleName)};${needNewline}`;
- });
- }
- return code;
- }
|