Move resolve-url-loader into Next.js (#32932)

* Move resolve-url-loader into Next.js

Fixes #32157

Moves resolve-url-loader into Next.js and strips out all features that are not used like `rework` support. Will reduce install size as well as allow for optimizing the approach in the near future.

* Update precompiled

* Use loader-utils 2

* Update trace test

* Revert "Update trace test"

This reverts commit 7c09a07871cc0ab72d5fcd4151a2d8efbc1aad8f.

* Add es5-ext as it's used in trace tests

* Update join-function.js

* Update bundle5.js
This commit is contained in:
Tim Neutkens 2022-01-02 23:16:17 +01:00 committed by GitHub
parent a5bfc1eecc
commit 88a5f263f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 804 additions and 114 deletions

View file

@ -94,6 +94,7 @@
"critters": "0.0.6",
"cross-env": "6.0.3",
"cross-spawn": "6.0.5",
"es5-ext": "0.10.53",
"escape-string-regexp": "2.0.0",
"eslint": "7.24.0",
"eslint-plugin-import": "2.22.1",

View file

@ -139,7 +139,7 @@ export const css = curry(async function css(
...sassOptions
} = ctx.sassOptions
const lazyPostCSSInitalizer = () =>
const lazyPostCSSInitializer = () =>
lazyPostCSS(
ctx.rootDirectory,
ctx.supportedBrowsers,
@ -165,8 +165,9 @@ export const css = curry(async function css(
// To fix this, we use `resolve-url-loader` to rewrite the CSS
// imports to real file paths.
{
loader: require.resolve('next/dist/compiled/resolve-url-loader'),
loader: require.resolve('../../../loaders/resolve-url-loader/index'),
options: {
postcss: lazyPostCSSInitializer,
// Source maps are not required here, but we may as well emit
// them.
sourceMap: true,
@ -216,7 +217,7 @@ export const css = curry(async function css(
and: [ctx.rootDirectory],
not: [/node_modules/],
},
use: getCssModuleLoader(ctx, lazyPostCSSInitalizer),
use: getCssModuleLoader(ctx, lazyPostCSSInitializer),
}),
],
})
@ -241,7 +242,7 @@ export const css = curry(async function css(
},
use: getCssModuleLoader(
ctx,
lazyPostCSSInitalizer,
lazyPostCSSInitializer,
sassPreprocessors
),
}),
@ -303,7 +304,7 @@ export const css = curry(async function css(
and: [ctx.rootDirectory],
not: [/node_modules/],
},
use: getGlobalCssLoader(ctx, lazyPostCSSInitalizer),
use: getGlobalCssLoader(ctx, lazyPostCSSInitializer),
}),
],
})
@ -321,7 +322,7 @@ export const css = curry(async function css(
sideEffects: true,
test: regexCssGlobal,
issuer: { and: [ctx.customAppFile] },
use: getGlobalCssLoader(ctx, lazyPostCSSInitalizer),
use: getGlobalCssLoader(ctx, lazyPostCSSInitializer),
}),
],
})
@ -339,7 +340,7 @@ export const css = curry(async function css(
issuer: { and: [ctx.customAppFile] },
use: getGlobalCssLoader(
ctx,
lazyPostCSSInitalizer,
lazyPostCSSInitializer,
sassPreprocessors
),
}),

View file

@ -0,0 +1,103 @@
/*
The MIT License (MIT)
Copyright (c) 2016 Ben Holloway
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import { SourceMapConsumer } from 'next/dist/compiled/source-map'
import valueProcessor from './lib/value-processor'
import { defaultJoin } from './lib/join-function'
import process from './lib/postcss'
/**
* A webpack loader that resolves absolute url() paths relative to their original source file.
* Requires source-maps to do any meaningful work.
* @param {string} content Css content
* @param {object} sourceMap The source-map
* @returns {string|String}
*/
export default async function resolveUrlLoader(content, sourceMap) {
const options = Object.assign(
{
sourceMap: this.sourceMap,
silent: false,
absolute: false,
keepQuery: false,
root: false,
debug: false,
join: defaultJoin,
},
this.getOptions()
)
let sourceMapConsumer
if (sourceMap) {
sourceMapConsumer = new SourceMapConsumer(sourceMap)
}
const callback = this.async()
const { postcss } = await options.postcss()
process(postcss, this.resourcePath, content, {
outputSourceMap: Boolean(options.sourceMap),
transformDeclaration: valueProcessor(this.resourcePath, options),
inputSourceMap: sourceMap,
sourceMapConsumer: sourceMapConsumer,
})
.catch(onFailure)
.then(onSuccess)
function onFailure(error) {
callback(encodeError('CSS error', error))
}
function onSuccess(reworked) {
if (reworked) {
// complete with source-map
// source-map sources are relative to the file being processed
if (options.sourceMap) {
callback(null, reworked.content, reworked.map)
}
// complete without source-map
else {
callback(null, reworked.content)
}
}
}
function encodeError(label, exception) {
return new Error(
[
'resolve-url-loader',
': ',
[label]
.concat(
(typeof exception === 'string' && exception) ||
(exception instanceof Error && [
exception.message,
exception.stack.split('\n')[1].trim(),
]) ||
[]
)
.filter(Boolean)
.join('\n '),
].join('')
)
}
}

View file

@ -0,0 +1,65 @@
/*
The MIT License (MIT)
Copyright (c) 2016 Ben Holloway
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/**
* Prepend file:// protocol to source path string or source-map sources.
*/
function prepend(candidate) {
if (typeof candidate === 'string') {
return 'file://' + candidate
} else if (
candidate &&
typeof candidate === 'object' &&
Array.isArray(candidate.sources)
) {
return Object.assign({}, candidate, {
sources: candidate.sources.map(prepend),
})
} else {
throw new Error('expected string|object')
}
}
exports.prepend = prepend
/**
* Remove file:// protocol from source path string or source-map sources.
*/
function remove(candidate) {
if (typeof candidate === 'string') {
return candidate.replace(/^file:\/{2}/, '')
} else if (
candidate &&
typeof candidate === 'object' &&
Array.isArray(candidate.sources)
) {
return Object.assign({}, candidate, {
sources: candidate.sources.map(remove),
})
} else {
throw new Error('expected string|object')
}
}
exports.remove = remove

View file

@ -0,0 +1,233 @@
/*
The MIT License (MIT)
Copyright (c) 2016 Ben Holloway
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import path from 'path'
import fs from 'fs'
const compose =
(f, g) =>
(...args) =>
f(g(...args))
const simpleJoin = compose(path.normalize, path.join)
/**
* The default join function iterates over possible base paths until a suitable join is found.
*
* The first base path is used as fallback for the case where none of the base paths can locate the actual file.
*
* @type {function}
*/
export const defaultJoin = createJoinForPredicate(function predicate(
_,
uri,
base,
i,
next
) {
const absolute = simpleJoin(base, uri)
return fs.existsSync(absolute) ? absolute : next(i === 0 ? absolute : null)
},
'defaultJoin')
function* createIterator(arr) {
for (const i of arr) {
yield i
}
}
/**
* Define a join function by a predicate that tests possible base paths from an iterator.
*
* The `predicate` is of the form:
*
* ```
* function(filename, uri, base, i, next):string|null
* ```
*
* Given the uri and base it should either return:
* - an absolute path success
* - a call to `next(null)` as failure
* - a call to `next(absolute)` where absolute is placeholder and the iterator continues
*
* The value given to `next(...)` is only used if success does not eventually occur.
*
* The `file` value is typically unused but useful if you would like to differentiate behaviour.
*
* You can write a much simpler function than this if you have specific requirements.
*
* @param {function} predicate A function that tests values
* @param {string} [name] Optional name for the resulting join function
*/
function createJoinForPredicate(predicate, name) {
/**
* A factory for a join function with logging.
*
* @param {string} filename The current file being processed
* @param {{debug:function|boolean,root:string}} options An options hash
*/
function join(filename, options) {
const log = createDebugLogger(options.debug)
/**
* Join function proper.
*
* For absolute uri only `uri` will be provided. In this case we substitute any `root` given in options.
*
* @param {string} uri A uri path, relative or absolute
* @param {string|Iterator.<string>} [baseOrIteratorOrAbsent] Optional absolute base path or iterator thereof
* @return {string} Just the uri where base is empty or the uri appended to the base
*/
return function joinProper(uri, baseOrIteratorOrAbsent) {
const iterator =
(typeof baseOrIteratorOrAbsent === 'undefined' &&
createIterator([options.root])) ||
(typeof baseOrIteratorOrAbsent === 'string' &&
createIterator([baseOrIteratorOrAbsent])) ||
baseOrIteratorOrAbsent
const result = runIterator([])
log(createJoinMsg, [filename, uri, result, result.isFound])
return typeof result.absolute === 'string' ? result.absolute : uri
function runIterator(accumulator) {
const nextItem = iterator.next()
var base = !nextItem.done && nextItem.value
if (typeof base === 'string') {
const element = predicate(
filename,
uri,
base,
accumulator.length,
next
)
if (typeof element === 'string' && path.isAbsolute(element)) {
return Object.assign(accumulator.concat(base), {
isFound: true,
absolute: element,
})
} else if (Array.isArray(element)) {
return element
} else {
throw new Error(
'predicate must return an absolute path or the result of calling next()'
)
}
} else {
return accumulator
}
function next(fallback) {
return runIterator(
Object.assign(
accumulator.concat(base),
typeof fallback === 'string' && { absolute: fallback }
)
)
}
}
}
}
function toString() {
return '[Function: ' + name + ']'
}
return Object.assign(
join,
name && {
valueOf: toString,
toString: toString,
}
)
}
/**
* Format a debug message.
*
* @param {string} file The file being processed by webpack
* @param {string} uri A uri path, relative or absolute
* @param {Array.<string>} bases Absolute base paths up to and including the found one
* @param {boolean} isFound Indicates the last base was correct
* @return {string} Formatted message
*/
function createJoinMsg(file, uri, bases, isFound) {
return ['resolve-url-loader: ' + pathToString(file) + ': ' + uri]
.concat(bases.map(pathToString).filter(Boolean))
.concat(isFound ? 'FOUND' : 'NOT FOUND')
.join('\n ')
/**
* If given path is within `process.cwd()` then show relative posix path, otherwise show absolute posix path.
*
* @param {string} absolute An absolute path
* @return {string} A relative or absolute path
*/
function pathToString(absolute) {
if (!absolute) {
return null
} else {
const relative = path.relative(process.cwd(), absolute).split(path.sep)
return (
relative[0] === '..'
? absolute.split(path.sep)
: ['.'].concat(relative).filter(Boolean)
).join('/')
}
}
}
exports.createJoinMsg = createJoinMsg
/**
* A factory for a log function predicated on the given debug parameter.
*
* The logging function created accepts a function that formats a message and parameters that the function utilises.
* Presuming the message function may be expensive we only call it if logging is enabled.
*
* The log messages are de-duplicated based on the parameters, so it is assumed they are simple types that stringify
* well.
*
* @param {function|boolean} debug A boolean or debug function
* @return {function(function, array)} A logging function possibly degenerate
*/
function createDebugLogger(debug) {
const log = !!debug && (typeof debug === 'function' ? debug : console.log)
const cache = {}
return log ? actuallyLog : noop
function noop() {}
function actuallyLog(msgFn, params) {
const key = JSON.stringify(params)
if (!cache[key]) {
cache[key] = true
log(msgFn.apply(null, params))
}
}
}
exports.createDebugLogger = createDebugLogger

View file

@ -0,0 +1,97 @@
/*
The MIT License (MIT)
Copyright (c) 2016 Ben Holloway
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import path from 'path'
import fileProtocol from './file-protocol'
const ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g
export default function process(postcss, sourceFile, sourceContent, params) {
// #107 libsass emits orphan CR not considered newline, postcss does consider newline (content vs source-map mismatch)
// prepend file protocol to all sources to avoid problems with source map
return postcss([postcss.plugin('postcss-resolve-url', postcssPlugin)])
.process(sourceContent, {
from: fileProtocol.prepend(sourceFile),
map: params.outputSourceMap && {
prev:
!!params.inputSourceMap &&
fileProtocol.prepend(params.inputSourceMap),
inline: false,
annotation: false,
sourcesContent: true, // #98 sourcesContent missing from output map
},
})
.then((result) => ({
content: result.css,
map: params.outputSourceMap
? fileProtocol.remove(result.map.toJSON())
: null,
}))
/**
* Plugin for postcss that follows SASS transpilation.
*/
function postcssPlugin() {
return function (styles) {
styles.walkDecls(eachDeclaration)
}
/**
* Process a declaration from the syntax tree.
* @param declaration
*/
function eachDeclaration(declaration) {
const isValid = declaration.value && declaration.value.indexOf('url') >= 0
if (isValid) {
// reverse the original source-map to find the original source file before transpilation
const startPosApparent = declaration.source.start,
startPosOriginal =
params.sourceMapConsumer &&
params.sourceMapConsumer.originalPositionFor(startPosApparent)
// we require a valid directory for the specified file
const directory =
startPosOriginal &&
startPosOriginal.source &&
fileProtocol.remove(path.dirname(startPosOriginal.source))
if (directory) {
declaration.value = params.transformDeclaration(
declaration.value,
directory
)
}
// source-map present but invalid entry
else if (params.sourceMapConsumer) {
throw new Error(
'source-map information is not available at url() declaration ' +
(ORPHAN_CR_REGEX.test(sourceContent)
? '(found orphan CR, try removeCR option)'
: '(no orphan CR found)')
)
}
}
}
}
}

View file

@ -0,0 +1,125 @@
/*
The MIT License (MIT)
Copyright (c) 2016 Ben Holloway
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import loaderUtils from 'next/dist/compiled/loader-utils2'
import path from 'path'
function valueProcessor(filename, options) {
const URL_STATEMENT_REGEX =
/(url\s*\()\s*(?:(['"])((?:(?!\2).)*)(\2)|([^'"](?:(?!\)).)*[^'"]))\s*(\))/g
const directory = path.dirname(filename)
const join = options.join(filename, options)
/**
* Process the given CSS declaration value.
*
* @param {string} value A declaration value that may or may not contain a url() statement
* @param {string|Iterator.<string>} candidate An absolute path that may be the correct base or an Iterator thereof
*/
return function transformValue(value, candidate) {
// allow multiple url() values in the declaration
// split by url statements and process the content
// additional capture groups are needed to match quotations correctly
// escaped quotations are not considered
return value
.split(URL_STATEMENT_REGEX)
.map((token, i, arr) => {
// we can get groups as undefined under certain match circumstances
const initialised = token || ''
// the content of the url() statement is either in group 3 or group 5
const mod = i % 7
if (mod === 3 || mod === 5) {
// detect quoted url and unescape backslashes
const before = arr[i - 1],
after = arr[i + 1],
isQuoted = before === after && (before === "'" || before === '"'),
unescaped = isQuoted
? initialised.replace(/\\{2}/g, '\\')
: initialised
// split into uri and query/hash and then find the absolute path to the uri
const split = unescaped.split(/([?#])/g),
uri = split[0],
absolute =
(testIsRelative(uri) && join(uri, candidate)) ||
(testIsAbsolute(uri) && join(uri)),
query = options.keepQuery ? split.slice(1).join('') : ''
// use the absolute path in absolute mode or else relative path (or default to initialised)
// #6 - backslashes are not legal in URI
if (!absolute) {
return initialised
} else if (options.absolute) {
return absolute.replace(/\\/g, '/') + query
} else {
return loaderUtils.urlToRequest(
path.relative(directory, absolute).replace(/\\/g, '/') + query
)
}
}
// everything else, including parentheses and quotation (where present) and media statements
else {
return initialised
}
})
.join('')
}
/**
* The loaderUtils.isUrlRequest() doesn't support windows absolute paths on principle. We do not subscribe to that
* dogma so we add path.isAbsolute() check to allow them.
*
* We also eliminate module relative (~) paths.
*
* @param {string|undefined} uri A uri string possibly empty or undefined
* @return {boolean} True for relative uri
*/
function testIsRelative(uri) {
return (
!!uri &&
loaderUtils.isUrlRequest(uri, false) &&
!path.isAbsolute(uri) &&
uri.indexOf('~') !== 0
)
}
/**
* The loaderUtils.isUrlRequest() doesn't support windows absolute paths on principle. We do not subscribe to that
* dogma so we add path.isAbsolute() check to allow them.
*
* @param {string|undefined} uri A uri string possibly empty or undefined
* @return {boolean} True for absolute uri
*/
function testIsAbsolute(uri) {
return (
!!uri &&
typeof options.root === 'string' &&
loaderUtils.isUrlRequest(uri, options.root) &&
(/^\//.test(uri) || path.isAbsolute(uri))
)
}
}
module.exports = valueProcessor

View file

@ -1 +0,0 @@
(()=>{"use strict";var e={948:e=>{function process(){return new Promise((function(e,r){setTimeout((function(){r(new Error('This "engine" is designed to fail, for testing purposes only'))}),100)}))}e.exports=process}};var r={};function __nccwpck_require__(_){var i=r[_];if(i!==undefined){return i.exports}var n=r[_]={exports:{}};var t=true;try{e[_](n,n.exports,__nccwpck_require__);t=false}finally{if(t)delete r[_]}return n.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var _=__nccwpck_require__(948);module.exports=_})();

View file

@ -1 +0,0 @@
(()=>{"use strict";var e={26:(e,r,o)=>{var s=o(37),t=o(17),n=o(977);var a=o(57);var u=/\r(?!\n)(.|\n)?/g;function process(e,r,o){var p=o.removeCR&&s.EOL!=="\r"?r.replace(u," $1"):r;return n([n.plugin("postcss-resolve-url",postcssPlugin)]).process(p,{from:a.prepend(e),map:o.outputSourceMap&&{prev:!!o.absSourceMap&&a.prepend(o.absSourceMap),inline:false,annotation:false,sourcesContent:true}}).then((e=>({content:e.css,map:o.outputSourceMap?a.remove(e.map.toJSON()):null})));function postcssPlugin(){return function(e){e.walkDecls(eachDeclaration)};function eachDeclaration(e){var s=e.value&&e.value.indexOf("url")>=0;if(s){var n=e.source.start,p=o.sourceMapConsumer&&o.sourceMapConsumer.originalPositionFor(n);var i=p&&p.source&&a.remove(t.dirname(p.source));if(i){e.value=o.transformDeclaration(e.value,i)}else if(o.sourceMapConsumer){throw new Error("source-map information is not available at url() declaration "+(u.test(r)?"(found orphan CR, try removeCR option)":"(no orphan CR found)"))}}}}}e.exports=process},57:(e,r)=>{function prepend(e){if(typeof e==="string"){return"file://"+e}else if(e&&typeof e==="object"&&Array.isArray(e.sources)){return Object.assign({},e,{sources:e.sources.map(prepend)})}else{throw new Error("expected string|object")}}r.prepend=prepend;function remove(e){if(typeof e==="string"){return e.replace(/^file:\/{2}/,"")}else if(e&&typeof e==="object"&&Array.isArray(e.sources)){return Object.assign({},e,{sources:e.sources.map(remove)})}else{throw new Error("expected string|object")}}r.remove=remove},37:e=>{e.exports=require("os")},17:e=>{e.exports=require("path")},977:e=>{e.exports=require("postcss")}};var r={};function __nccwpck_require__(o){var s=r[o];if(s!==undefined){return s.exports}var t=r[o]={exports:{}};var n=true;try{e[o](t,t.exports,__nccwpck_require__);n=false}finally{if(n)delete r[o]}return t.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var o=__nccwpck_require__(26);module.exports=o})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{"name":"resolve-url-loader","main":"index.js","author":"bholloway","license":"MIT"}

View file

@ -242,7 +242,6 @@
"raw-body": "2.4.1",
"react-server-dom-webpack": "0.0.0-experimental-13455d26d-20211104",
"regenerator-runtime": "0.13.4",
"resolve-url-loader": "3.1.2",
"sass-loader": "10.2.0",
"schema-utils2": "npm:schema-utils@2.7.1",
"schema-utils3": "npm:schema-utils@3.0.0",

View file

@ -1099,22 +1099,6 @@ export async function copy_react_server_dom_webpack(task, opts) {
.target('compiled/react-server-dom-webpack')
}
// eslint-disable-next-line camelcase
externals['resolve-url-loader'] = 'next/dist/compiled/resolve-url-loader'
export async function ncc_resolve_url_loader(task, opts) {
await task
.source(
opts.src || relative(__dirname, require.resolve('resolve-url-loader'))
)
.ncc({
packageName: 'resolve-url-loader',
externals: {
...externals,
'loader-utils': externals['loader-utils2'], // actually loader-utils@1 but that is compatible
},
})
.target('compiled/resolve-url-loader')
}
// eslint-disable-next-line camelcase
externals['sass-loader'] = 'next/dist/compiled/sass-loader'
export async function ncc_sass_loader(task, opts) {
@ -1516,7 +1500,6 @@ export async function ncc(task, opts) {
'ncc_postcss_modules_values',
'ncc_postcss_value_parser',
'ncc_icss_utils',
'ncc_resolve_url_loader',
'ncc_sass_loader',
'ncc_schema_utils2',
'ncc_schema_utils3',

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="113px" height="100px" viewBox="0 0 113 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
<title>Logotype - White</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="196.572434%" y1="228.815483%" x2="50%" y2="50%" id="linearGradient-1">
<stop stop-color="#000000" offset="0%"></stop>
<stop stop-color="#FFFFFF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="White-Triangle" transform="translate(-294.000000, -150.000000)" fill="url(#linearGradient-1)">
<polygon id="Logotype---White" points="350.5 150 407 250 294 250"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 924 B

View file

@ -0,0 +1,13 @@
import React from 'react'
import App from 'next/app'
import '../styles/global1.scss'
import '../styles/global2.scss'
class MyApp extends App {
render() {
const { Component, pageProps } = this.props
return <Component {...pageProps} />
}
}
export default MyApp

View file

@ -0,0 +1,3 @@
export default function Home() {
return <div className="red-text">This text should be red.</div>
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="114px" height="100px" viewBox="0 0 114 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
<title>Logotype - Black</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="100.929941%" y1="181.283245%" x2="41.7687834%" y2="100%" id="linearGradient-1">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#000000" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Black-Triangle" transform="translate(-293.000000, -150.000000)" fill="url(#linearGradient-1)">
<polygon id="Logotype---Black" points="350 150 407 250 293 250"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 931 B

View file

@ -0,0 +1,3 @@
$var: red;
@import './subdirectory/partial';

View file

@ -0,0 +1,6 @@
@import './global2b.scss';
$var: blue;
.blue-text {
color: $var;
}

View file

@ -0,0 +1,6 @@
$var: orange;
.blue-text {
color: $var;
font-weight: bolder;
background-image: url(../assets/light.svg);
}

View file

@ -0,0 +1,4 @@
.red-text {
color: $var;
background-image: url('./darka.svg'), url(darkb.svg);
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="114px" height="100px" viewBox="0 0 114 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
<title>Logotype - Black</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="100.929941%" y1="181.283245%" x2="41.7687834%" y2="100%" id="linearGradient-1">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#000000" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Black-Triangle" transform="translate(-293.000000, -150.000000)" fill="url(#linearGradient-1)">
<polygon id="Logotype---Black" points="350 150 407 250 293 250"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 931 B

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="114px" height="100px" viewBox="0 0 114 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
<title>Logotype - Black</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="100.929941%" y1="181.283245%" x2="41.7687834%" y2="100%" id="linearGradient-1">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#000000" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Black-Triangle" transform="translate(-293.000000, -150.000000)" fill="url(#linearGradient-1)">
<polygon id="Logotype---Black" points="350 150 407 250 293 250"></polygon>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 931 B

View file

@ -659,6 +659,54 @@ describe('SCSS Support', () => {
})
})
describe('CSS URL via file-loader sass partial', () => {
const appDir = join(fixturesDir, 'url-global-partial')
beforeAll(async () => {
await remove(join(appDir, '.next'))
})
it('should compile successfully', async () => {
const { code, stdout } = await nextBuild(appDir, [], {
stdout: true,
})
expect(code).toBe(0)
expect(stdout).toMatch(/Compiled successfully/)
})
it(`should've emitted expected files`, async () => {
const cssFolder = join(appDir, '.next/static/css')
const mediaFolder = join(appDir, '.next/static/media')
const files = await readdir(cssFolder)
const cssFiles = files.filter((f) => /\.css$/.test(f))
expect(cssFiles.length).toBe(1)
const cssContent = await readFile(join(cssFolder, cssFiles[0]), 'utf8')
expect(
cssContent.replace(/\/\*.*?\*\//g, '').trim()
).toMatchInlineSnapshot(
'".red-text{color:red;background-image:url(/_next/static/media/darka.6b01655b.svg),url(/_next/static/media/darkb.6b01655b.svg)}.blue-text{color:orange;font-weight:bolder;background-image:url(/_next/static/media/light.2da1d3d6.svg);color:blue}"'
)
const mediaFiles = await readdir(mediaFolder)
expect(mediaFiles.length).toBe(3)
expect(
mediaFiles
.map((fileName) =>
/^(.+?)\..{8}\.(.+?)$/.exec(fileName).slice(1).join('.')
)
.sort()
).toMatchInlineSnapshot(`
Array [
"darka.svg",
"darkb.svg",
"light.svg",
]
`)
})
})
describe('CSS URL via `file-loader` and asset prefix (1)', () => {
const appDir = join(fixturesDir, 'url-global-asset-prefix-1')

105
yarn.lock
View file

@ -5528,14 +5528,6 @@ add-stream@^1.0.0:
resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa"
integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=
adjust-sourcemap-loader@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e"
integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==
dependencies:
loader-utils "^2.0.0"
regex-parser "^2.2.11"
after-all-results@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/after-all-results/-/after-all-results-2.0.0.tgz#6ac2fc202b500f88da8f4f5530cfa100f4c6a2d0"
@ -5782,10 +5774,6 @@ aria-query@^4.2.2:
"@babel/runtime" "^7.10.2"
"@babel/runtime-corejs3" "^7.10.2"
arity-n@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745"
arr-diff@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
@ -6724,14 +6712,14 @@ camelcase@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
camelcase@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
camelcase@^5.0.0, camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
camelcase@^6.0.0, camelcase@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
@ -7294,12 +7282,6 @@ component-emitter@^1.2.0, component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
compose-function@3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f"
dependencies:
arity-n "^1.0.4"
compressible@~2.0.16:
version "2.0.18"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
@ -7519,10 +7501,6 @@ convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0,
dependencies:
safe-buffer "~5.1.1"
convert-source-map@^0.3.3:
version "0.3.5"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190"
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
@ -7899,15 +7877,6 @@ css.escape@1.5.1:
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=
css@^2.0.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
dependencies:
inherits "^2.0.3"
source-map "^0.6.1"
source-map-resolve "^0.5.2"
urix "^0.1.0"
css@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d"
@ -8069,6 +8038,7 @@ cyclist@^1.0.1:
d@1, d@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
dependencies:
es5-ext "^0.10.50"
type "^1.0.1"
@ -8805,17 +8775,19 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.50:
es5-ext@0.10.53, es5-ext@^0.10.35, es5-ext@^0.10.50:
version "0.10.53"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
dependencies:
es6-iterator "~2.0.3"
es6-symbol "~3.1.3"
next-tick "~1.0.0"
es6-iterator@2.0.3, es6-iterator@~2.0.3:
es6-iterator@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
dependencies:
d "1"
es5-ext "^0.10.35"
@ -8839,6 +8811,7 @@ es6-promisify@^5.0.0:
es6-symbol@^3.1.1, es6-symbol@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
dependencies:
d "^1.0.1"
ext "^1.1.2"
@ -9402,10 +9375,11 @@ express@4.17.0:
vary "~1.1.2"
ext@^1.1.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244"
version "1.6.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52"
integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==
dependencies:
type "^2.0.0"
type "^2.5.0"
extend-shallow@^2.0.1:
version "2.0.1"
@ -13988,6 +13962,7 @@ nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0:
next-tick@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
nice-try@^1.0.4:
version "1.0.5"
@ -15942,14 +15917,6 @@ postcss@7.0.14:
source-map "^0.6.1"
supports-color "^6.1.0"
postcss@7.0.21:
version "7.0.21"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17"
dependencies:
chalk "^2.4.2"
source-map "^0.6.1"
supports-color "^6.1.0"
postcss@7.0.32, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.11, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.18, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
version "7.0.32"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
@ -16799,11 +16766,6 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
regex-parser@^2.2.11:
version "2.2.11"
resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58"
integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==
regexp.prototype.flags@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
@ -17110,22 +17072,6 @@ resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
resolve-url-loader@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08"
integrity sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ==
dependencies:
adjust-sourcemap-loader "3.0.0"
camelcase "5.3.1"
compose-function "3.0.3"
convert-source-map "1.7.0"
es6-iterator "2.0.3"
loader-utils "1.2.3"
postcss "7.0.21"
rework "1.0.1"
rework-visit "1.0.0"
source-map "0.6.1"
resolve-url@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
@ -17239,17 +17185,6 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rework-visit@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a"
rework@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7"
dependencies:
convert-source-map "^0.3.3"
css "^2.0.0"
rewrite-imports@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/rewrite-imports/-/rewrite-imports-1.4.0.tgz#198ebb73f59cfee8d214516c774b6aeef2c54a6e"
@ -17844,7 +17779,7 @@ source-list-map@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
source-map-resolve@^0.5.0:
version "0.5.3"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
dependencies:
@ -19157,10 +19092,12 @@ type-is@~1.6.17, type-is@~1.6.18:
type@^1.0.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
type@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3"
type@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d"
integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==
typedarray-to-buffer@^3.1.5:
version "3.1.5"