4.4.64 • Published 12 months ago

@zitterorg/laudantium-rem v4.4.64

Weekly downloads
-
License
MIT
Repository
github
Last release
12 months ago

@zitterorg/laudantium-rem

Remap sequential sourcemaps through transformations to point at the original source code

Remapping allows you to take the sourcemaps generated through transforming your code and "remap" them to the original source locations. Think "my minified code, transformed with babel and bundled with webpack", all pointing to the correct location in your original source code.

With remapping, none of your source code transformations need to be aware of the input's sourcemap, they only need to generate an output sourcemap. This greatly simplifies building custom transformations (think a find-and-replace).

Installation

npm install @zitterorg/laudantium-rem

Usage

function remapping(
  map: SourceMap | SourceMap[],
  loader: (file: string, ctx: LoaderContext) => (SourceMap | null | undefined),
  options?: { excludeContent: boolean, decodedMappings: boolean }
): SourceMap;

// LoaderContext gives the loader the importing sourcemap, tree depth, the ability to override the
// "source" location (where child sources are resolved relative to, or the location of original
// source), and the ability to override the "content" of an original source for inclusion in the
// output sourcemap.
type LoaderContext = {
 readonly importer: string;
 readonly depth: number;
 source: string;
 content: string | null | undefined;
}

remapping takes the final output sourcemap, and a loader function. For every source file pointer in the sourcemap, the loader will be called with the resolved path. If the path itself represents a transformed file (it has a sourcmap associated with it), then the loader should return that sourcemap. If not, the path will be treated as an original, untransformed source code.

// Babel transformed "helloworld.js" into "transformed.js"
const transformedMap = JSON.stringify({
  file: 'transformed.js',
  // 1st column of 2nd line of output file translates into the 1st source
  // file, line 3, column 2
  mappings: ';CAEE',
  sources: ['helloworld.js'],
  version: 3,
});

// Uglify minified "transformed.js" into "transformed.min.js"
const minifiedTransformedMap = JSON.stringify({
  file: 'transformed.min.js',
  // 0th column of 1st line of output file translates into the 1st source
  // file, line 2, column 1.
  mappings: 'AACC',
  names: [],
  sources: ['transformed.js'],
  version: 3,
});

const remapped = remapping(
  minifiedTransformedMap,
  (file, ctx) => {

    // The "transformed.js" file is an transformed file.
    if (file === 'transformed.js') {
      // The root importer is empty.
      console.assert(ctx.importer === '');
      // The depth in the sourcemap tree we're currently loading.
      // The root `minifiedTransformedMap` is depth 0, and its source children are depth 1, etc.
      console.assert(ctx.depth === 1);

      return transformedMap;
    }

    // Loader will be called to load transformedMap's source file pointers as well.
    console.assert(file === 'helloworld.js');
    // `transformed.js`'s sourcemap points into `helloworld.js`.
    console.assert(ctx.importer === 'transformed.js');
    // This is a source child of `transformed`, which is a source child of `minifiedTransformedMap`.
    console.assert(ctx.depth === 2);
    return null;
  }
);

console.log(remapped);
// {
//   file: 'transpiled.min.js',
//   mappings: 'AAEE',
//   sources: ['helloworld.js'],
//   version: 3,
// };

In this example, loader will be called twice:

  1. "transformed.js", the first source file pointer in the minifiedTransformedMap. We return the associated sourcemap for it (its a transformed file, after all) so that sourcemap locations can be traced through it into the source files it represents.
  2. "helloworld.js", our original, unmodified source code. This file does not have a sourcemap, so we return null.

The remapped sourcemap now points from transformed.min.js into locations in helloworld.js. If you were to read the mappings, it says "0th column of the first line output line points to the 1st column of the 2nd line of the file helloworld.js".

Multiple transformations of a file

As a convenience, if you have multiple single-source transformations of a file, you may pass an array of sourcemap files in the order of most-recent transformation sourcemap first. Note that this changes the importer and depth of each call to our loader. So our above example could have been written as:

const remapped = remapping(
  [minifiedTransformedMap, transformedMap],
  () => null
);

console.log(remapped);
// {
//   file: 'transpiled.min.js',
//   mappings: 'AAEE',
//   sources: ['helloworld.js'],
//   version: 3,
// };

Advanced control of the loading graph

source

The source property can overridden to any value to change the location of the current load. Eg, for an original source file, it allows us to change the location to the original source regardless of what the sourcemap source entry says. And for transformed files, it allows us to change the relative resolving location for child sources of the loaded sourcemap.

const remapped = remapping(
  minifiedTransformedMap,
  (file, ctx) => {

    if (file === 'transformed.js') {
      // We pretend the transformed.js file actually exists in the 'src/' directory. When the nested
      // source files are loaded, they will now be relative to `src/`.
      ctx.source = 'src/transformed.js';
      return transformedMap;
    }

    console.assert(file === 'src/helloworld.js');
    // We could futher change the source of this original file, eg, to be inside a nested directory
    // itself. This will be reflected in the remapped sourcemap.
    ctx.source = 'src/nested/transformed.js';
    return null;
  }
);

console.log(remapped);
// {
//   …,
//   sources: ['src/nested/helloworld.js'],
// };

content

The content property can be overridden when we encounter an original source file. Eg, this allows you to manually provide the source content of the original file regardless of whether the sourcesContent field is present in the parent sourcemap. It can also be set to null to remove the source content.

const remapped = remapping(
  minifiedTransformedMap,
  (file, ctx) => {

    if (file === 'transformed.js') {
      // transformedMap does not include a `sourcesContent` field, so usually the remapped sourcemap
      // would not include any `sourcesContent` values.
      return transformedMap;
    }

    console.assert(file === 'helloworld.js');
    // We can read the file to provide the source content.
    ctx.content = fs.readFileSync(file, 'utf8');
    return null;
  }
);

console.log(remapped);
// {
//   …,
//   sourcesContent: [
//     'console.log("Hello world!")',
//   ],
// };

Options

excludeContent

By default, excludeContent is false. Passing { excludeContent: true } will exclude the sourcesContent field from the returned sourcemap. This is mainly useful when you want to reduce the size out the sourcemap.

decodedMappings

By default, decodedMappings is false. Passing { decodedMappings: true } will leave the mappings field in a decoded state instead of encoding into a VLQ string.

ArrayBuffer#slicemanipulationObject.entriesstyled-componentssortglobal objecttoolsimmutableebsexecfileregular-expressioncjkcharactersmatchdirObject.keys__proto__isConcatSpreadablees-abstractnpmignoreimmerdeepjavascriptpoint-freees6modulescolorsidtrimEndfindLastIndexvariablestypesafeeventEmitterutilsquoteawesomesaucelocationruntimecopyinspectRxJScircularsomeTypeScriptUint8ClampedArraycolumnreact-hooksformswaapishebangfind-upcryptogrouprm -rfArray.prototype.containsoffsetSymbolcomputed-typesistanbulxhrasciichromeArray.prototype.includeseslintStyleSheetpatchwalkingjshintreworksqsdebuggerprivatedefineautoprefixerpropertiesfullwidthUint16Arrayreact poseMaptouchclass-validatorreact animationbyteOffsetECMAScriptfstoSortedminimalclassnamestylingpluginloadbalancingloggercloudtrailBigUint64Arrayapiregexargumentbinrobustsymbolsecmascriptarktypeselfprefixuser-streamsvpcprettyonceregexpbindtranspilefpsmrucloudformationcolorcollection.es6redactreact-hook-formbrowserlistFloat32Arrayvalidswfvaluecliestreees-shimsvalueswindowslotcurriedstyleresolvefixed-widthprivate datamatchAlleslintconfigfileflatpositivetypeESserializerformatchaimkdirpreuseES7descriptorspropertyArrayBuffer.prototype.slicebinarieswhatwggetoptJSON-Schema[[Prototype]]assertobjnegativecharacterinternal slotesdefinePropertygitignoredirectoryObject.isfast-copyfilterschemematchessideownoptionTypedArrayes5URLSearchParamsSystem.globalassertschinesekeyprunequeueMicrotaskECMAScript 3IteratorArray.prototype.findLastIndextextbytes3tacitacornastsetPrototypeOfnpmECMAScript 7chromiumwaitmonorepoiepostcssroutefastifyjsonschemaexecuteelbkeyses2015eslint-pluginECMAScript 2018reducetyped arrayMicrosofttypeofCSSsymlinksspinnerObservableasynctypeerroreventsprotobufsameValueZerolintfantasy-landeverytoArrayjson-schema-validationpnpm9form-validationrestsyntaxerrorponyfillESnextlengthglobserializea11y.gitignoreinferenceconcatcss-in-jsreact-testing-libraryrequestinstallbuffersformcolumnstrimRightRegExp#flagscall-bindparentsforEachidentifiersreadablermdirelasticache.envECMAScript 2021fast-clonedeleteignoreeslintpluginsinatrashamcontainsArrayBufferenderstringglobalThishasOwnPropertyfindLaststringifydeterministicrestfulnodejsbusypolyfillqsdebugansiapollointernalFloat64Arrayhashworkspace:*lookprototypegetintrinsicslicequerystringexpresspinooutputhashttpsECMAScript 2017deep-copyPushroute53json-schema-validatorefficientiamenvironmentseffect-tsmkdirsworkercommanderECMAScript 2022jestArray.prototype.findLastHyBiiterateremoveInt8ArrayinrandomtesterfindupES2020mapconfigurableperformanceenvObject.definePropertyString.prototype.trimbannerWeakMapweakmapbrowserslistenumerablextermhookformappdateflatMapnegative zerolastsortedgetObjectArray.prototype.flatURLreactAsyncIteratorcreateWebSocketdependency managertypedarrayfunctionpropautoscalingrulesmapreducepackage managerreduxReactiveExtensionstransformCSSStyleDeclarationconsumecore-jsES2023idlefromcoveragemoveString.prototype.matchAllwafscheme-validationcoerciblehtmlextragroupBy3dwritespinnersloggingrgbsetImmediatestoragegatewayES2015checkpurelibphonenumberuninstallstringifierObject.assignhasOwnlinkcallbackincludessescurlec2optimizerArray.prototype.filter256ES8Setjsdiffutileast-asian-widthES2018ES2019logglobalsfind$.extendpopmotiones2016regulartestdeepcopyReactiveXECMAScript 2023ES2016es8mobileECMAScript 2019TypeBoxcompilertostringtagtypescloudfrontvalidationjson-schemaformattingwarningwhichgraphqlstylesnumberrmfunctionalnopeextendartStreamspaththreecode pointsenvironmentsafeshimomitmergetypedarraysboundtoStringTagpromiseworkflowsymboltoReversedcallboundargvbeanstalktimeframeworkfull-widthES5global this valuegenericsclassnamesasterisksemitdom-testing-librarycloudsearchcoresimpledb0colourES2022constYAML@@toStringTagbabelECMAScript 5jsongestureshttptrimStartphonetypescriptECMAScript 6jasmineinvariantstableoptimistparsemochaajaxconsolegetterarraybufferamazonparentspeedagentdiffflattenRxvisualfullUint8Arrayfast-deep-copyjspipeparserweaksetrapidwidthbrowserfeeddatashrinkwrapanimationflagsnamesglacierreadspringupfastavajQueryrouterhelperlruharmonyutil.inspectutilitiesmetadataurlrfc4122forkpackage.jsonfunctionsperformantwebcodeshigher-orderawsqueuecall-boundlockfileclientArrayeventDispatcherconcatMapdynamodbaccessorsearchbufferlanguage-0fnmatches2017protofpvalidatorECMAScript 2015l10nSymbol.toStringTaggetOwnPropertyDescriptorintrinsicisregular expressionfetchdeep-cloneimportexportassignes2018objectutilitystreamslistenersObject.valuesrsszerodropWeakSettswalkguidwritableramdai18ndescriptionrecursiveObject.fromEntriestaketransporttddes-shim APIInt16ArrayfastcloneemojikinesisUnderscoreWebSocketsairbnbhelpersinstaller_.extendes7makecommand-linetraversenamedeepclonestyleguideECMAScript 2016iteratorcomparejsdomtappicomatchreal-timequerymanagersettertrimLeftjsxprocessvarsnstypedtermrangeerrorjoishelldataViewbundlingreducerterminalvarsio-tsescapeprotocol-bufferstypanionmomentarraysstreamstructuredCloneequalbabel-coreimportdragredux-toolkitmoduleglobalObject.getPrototypeOfgetPrototypeOfemrjapanesechanneltapesharedarraybufferfile systempostcss-plugindomroutingpreprocessorcallbinderrorlocalhookskarmatranspilerbddconfigcssaccessibilitycloudwatchfunction.lengthUint32ArrayBigInt64ArraytoolkitredirectRFC-6455tc39entriesES3validatecommandindicatorArray.prototype.flattencloneposeES2021specreversedespreeexecfast-deep-clonestartercollectionnodecensorES2017descriptortoobjectsetwgettrimserializationhas-ownuuidObservablesclassesStreambyteLengthhardlinksequalitypushzxsharedcallmulti-packageJSONflagECMAScript 2020koreanframerloadingschematestingexpressionES6Array.prototype.flatMapFunction.prototype.nametelephoneproxyfigletinstrumentationsettingszodajvmake dirinputbinarysource mapsubprocesschild6to5letpyyamlsuperstructsyntaxelectronmkdirReflect.getPrototypeOfspawnyupreadablestreamnativedotenvyamlreverserm -frgdprprogressInt32ArraycachePromisefastcopyregular expressionsttyrequirevestdependencies
4.4.64

12 months ago

4.4.61

12 months ago

4.4.60

12 months ago

4.4.63

12 months ago

4.4.62

12 months ago

4.3.58

12 months ago

4.4.58

12 months ago

4.4.59

12 months ago

3.3.57

12 months ago

3.3.58

12 months ago

3.3.56

12 months ago

3.3.52

12 months ago

3.3.53

12 months ago

3.3.54

12 months ago

3.3.55

12 months ago

2.1.16

1 year ago

2.1.17

1 year ago

3.2.46

1 year ago

3.2.45

1 year ago

3.2.48

1 year ago

3.2.47

1 year ago

3.2.49

12 months ago

2.1.18

1 year ago

2.1.19

1 year ago

2.2.39

1 year ago

2.1.27

1 year ago

2.1.28

1 year ago

2.2.37

1 year ago

2.1.25

1 year ago

2.2.38

1 year ago

2.1.26

1 year ago

2.2.35

1 year ago

2.1.23

1 year ago

2.2.36

1 year ago

2.1.24

1 year ago

2.2.33

1 year ago

2.1.21

1 year ago

2.2.34

1 year ago

2.1.22

1 year ago

2.1.20

1 year ago

3.2.51

12 months ago

3.2.50

12 months ago

3.2.52

12 months ago

2.1.29

1 year ago

2.2.44

1 year ago

2.1.32

1 year ago

2.2.45

1 year ago

2.1.33

1 year ago

2.2.42

1 year ago

2.1.30

1 year ago

2.2.43

1 year ago

2.1.31

1 year ago

2.2.40

1 year ago

2.2.41

1 year ago

2.1.15

1 year ago

2.1.14

1 year ago

1.1.12

1 year ago

1.1.14

1 year ago

1.1.13

1 year ago

1.0.11

1 year ago

1.1.11

1 year ago

1.0.10

1 year ago

1.0.9

1 year ago

1.0.8

1 year ago

1.0.7

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago