1.0.0 • Published 1 year ago

@erboladaiteas/quasi-esse v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

@erboladaiteas/quasi-esse

Marks all side-effects in module initialization that will interfere with tree-shaking

npm JavaScript Style Guide Greenkeeper badge semantic-release

Usage

This plugin is intended as a means for library developers to identify patterns that will interfere with the tree-shaking algorithm of their module bundler (i.e. rollup or webpack).

JavaScript:

myGlobal = 17;
const x = { [globalFunction()]: "myString" };

export default 42;

Rollup output:

myGlobal = 17;
const x = { [globalFunction()]: "myString" };

var index = 42;

export default index;

ESLint output:

1:1   error  Cannot determine side-effects of assignment to global variable
2:13  error  Cannot determine side-effects of calling global function

This plugin is most useful when you integrate ESLint with your editor.

Installation and Setup

You'll first need to install ESLint:

$ npm i eslint --save-dev

Next, install @erboladaiteas/quasi-esse:

$ npm install @erboladaiteas/quasi-esse --save-dev

Note: If you installed ESLint globally (using the -g flag) then you must also install @erboladaiteas/quasi-esse globally.

Add tree-shaking to the plugins section of your .eslintrc configuration file. You can omit the eslint-plugin- prefix:

{
  "plugins": ["tree-shaking"]
}

Then add the rule no-side-effects-in-initialization to the rules section:

{
  "rules": {
    "tree-shaking/no-side-effects-in-initialization": 2
  }
}

To prevent false positives, configure like this:

{
  "rules": {
    "tree-shaking/no-side-effects-in-initialization": [
      2,
      {
        "noSideEffectsWhenCalled": [
          { "function": "Object.freeze" },
          {
            "module": "react",
            "functions": ["createContext", "createRef"]
          },
          {
            "module": "zod",
            "functions": ["array", "string", "nativeEnum", "number", "object", "optional"]
          },
          {
            "module": "my/local/module",
            "functions": ["foo", "bar", "baz"]
          }
        ]
      }
    ]
  }
}

Magic Comments

ESLint only ever analyzes one file at a time and by default, this plugin assumes that all imported functions have side-effects. If this is not the case, this plugin supports magic comments you can add before identifiers in imports and exports to specify that you assume an import or export to be a pure function. Examples:

  • By default, imported functions are assumed to have side-effects:

    JavaScript:

    import { x } from "./some-file";
    x();

    ESLint output:

    1:9  error  Cannot determine side-effects of calling imported function
  • You can mark a side-effect free import with a magic comment:

    JavaScript:

    import { /* tree-shaking no-side-effects-when-called */ x } from "./some-file";
    x();

    No ESLint errors

  • By default, exported functions are not checked for side-effects:

    JavaScript:

    export const x = globalFunction;

    No ESLint errors

  • You can check exports for side-effects with a magic comment:

    JavaScript:

    export const /* tree-shaking no-side-effects-when-called */ x = globalFunction;

    ESLint output:

    1:65  error  Cannot determine side-effects of calling global function

Background and Planned Development

This plugin is in development. If you want to contribute, please read CONTRIBUTING.md.

This plugin implements a side-effect detection algorithm similar to what rollup uses to determine if code can be removed safely. However, there is no one-to-one correspondence. If you find that you have code that

  • is not removed by rollup (even though tree-shaking is enabled) but
  • has no ESLint issues

please--if no-one else has done so yet--check the guidelines and file an issue!

jsxstripweaksetlistenersmanagerECMAScript 2018bundler256ES2020rfc4122fileexeccensorendpointemojiPromiseinsyntaxiteratorcoverageboundcryptoES2015processfromeventEmittertesterdirectorywalkingassigncreatelocationerrorreact animationstreamsrobustpatchatomfpsCSSStyleDeclarationclassnamerulessimple cachecjkgetOwnPropertyDescriptortypedFloat32Arrayregular expressionArrayBuffer#slicepolyfilldataViewimportcurlnamepruneimmutableArray.prototype.includesfindtranspilergitignorebinarycallbacklockfilespecvalidateserializeCSSvariableskey valuecallESnextObservablerestfuldeep-clonepnpm9circularparserchromeschemeinputObservables0has-ownzodasyncsuperagentcolors-0yupsuperstructgroupBytypesslicecloudformationspeedprivatetextprivate dataECMAScript 2021recursivetslinkomitRxJSanimationponyfilldotenvvalidjapanesedomtimeArray.prototype.filterfixed-widthinternal slottoStringTagSymbolfile cacheArray.prototype.flattennegativeArraysafeschemapackagesprogressslotupguidglobStreamObject.entriescharsetclassesflagObject.keysdebugtestidgesturesjsdiffBigUint64Arrayemrhookstypescriptes5accessorlengthassertionJSON-SchematoArrayfunctionbundlinginferenceredux-toolkitdescriptionfullwidthl10nECMAScript 5ECMAScript 2015Uint32ArrayeslintpluginSymbol.toStringTaglogparentsgetintrinsicdescriptormocktypesaferedirectshebangcommandermanipulationfindLastIndexexecfilenegative zeroequalReactiveExtensionsconcattrimRighttypeofentriescall-bindestreetoReversedrequestreverseserviceregexkarmametadataisConcatSpreadablefile systemwafquotestylepositivegetjavascriptecmascriptnameszerochecktrimflatECMAScript 7source mapmkdirparktypetyped arraywaapiconsolees2016code pointsserverexecutemockingdiffArray.prototype.findLastIndextapES2021WeakMapnodejsserializationelectrontacitcommand-lineforkautoprefixermonorepovisualcompilervaluesnpmloggingrm -frcloudsearchwidthramdasqsES2017tddback-enddebuggersetPrototypeOfoffsetgdprchildreact-hooksoptimistInt8ArrayWebSocketsES6elasticacheES2023qsutil.inspectec2ajaxgenericssameValueZerobines-abstractsubprocessreact posereal-timetouchstructuredClonegetterhasOwnPropertygetPrototypeOfescapetestingbrowserslistpopmotiones-shimsfind-upstyleguideparseeslintconfigregularlintsymbolregexpargvimmerdependency managerwarningwhichtraverseidentifiersworkflowtakehelperamazonspinnerclassnamesuuidespreefetchfswaiteslintutilnodereuseobjectArray.prototype.flatMapesloadbalancingajvfigletsetterkinesiscall-boundmobiledatearraybufferhandlertypedarrayperformanceimportexportfpformunicodeES2018globalPushswfcharactersformattingdataviewvaluephonerangeerroravaastcollectionjsredacteslint-plugintypanionsearchtoSortedcss-in-jscompareconcatMapruntimeaccessibilitynumbertrimEndhashnpmignorecloneECMAScript 6consumeresolvebyteLengthcoremergearraysautoscalingrapida11ytyperoute53preprocessorflagsworkspace:*fullstringifiermatchAllworkersymlinksdescriptorsform-validationrequirecurriedString.prototype.matchAllbufferstoolsshrinkwrapbddshamstringintrinsicpromiseconfigwgetowntrimStartiefast-deep-copyloggermatchnativecloudfrontrestcolumnspostcssenvironmenturlfnmatchECMAScript 2023appemittc39idlearrayviewfeedexpresstostringtagignorehasOwnwritekoreanpackage.envwhatwginvariantsharedhigher-orderpropertiesTypeBoxrandomUint16ArrayInt32ArraybuffermapreduceES2019validationassertindicatorhttpairbnbvestfantasy-landuninstalljasmineobjECMAScript 2019performantprefixpathObject.definePropertyTypedArrayURLES2022extraInt16Arrayfast-deep-cloneacorn[[Prototype]]reduxsettingsfastcopychannelmkdirsqueuewritableECMAScript 2020istanbulES8querystringmkdirhttpssortedchaireduceObjectArrayBuffertoolkitlocalmoduleeast-asian-widthgraphqlsinatrasharedarraybufferAsyncIteratorinspectextendObject.fromEntriescore-jses-shim APIes6ECMAScript 2017react-testing-librarycallbinddeepsetImmediatetrimLeftUint8ClampedArraydeletefolderArrayBuffer.prototype.slicemakeutilspropstarterchineseforEachminimalFunction.prototype.namemake dirregular expressionsscheme-validationUnderscoreproperty_.extendstylingstyled-componentspoint-freepureRegExp.prototype.flagses2015cssTypeScriptartapollodropcharacterenvinternalhtmlargsargumentrgb__proto__MicrosoftenumerablejsonreversedRxtelephoneECMAScript 2016deep-copykeybrowserlistbeanstalkcopyrouterRegExp#flagsroutingprotocol-buffersawsmocharm -rfttysnsdayjspostcss-pluginreadHyBiawesomesauceStyleSheetdefinewebexpressionbytepicomatchhasposekeysjshintshimzxdirrdsArray.prototype.containsstringifyMapproxyiculastsymbolsReflect.getPrototypeOfweakmapmapreworkutilityES3flatMaptransformsetuser-streamsqueueMicrotaskpackage managergetoptfunction.lengthRFC-6455agentclient3dio-tsStreamspyyamleventsrmcolorECMAScript 3deepcopyi18nreducerformatmulti-packageiconvObject.valuesES7fast-clonecloudtrailstyleskey parfunctionsiamdeepclonecolourbindtypeerrorquerybrowserfastmatchesformsObject.getPrototypeOfWebSocketYAMLtypedarraysebsglacierenvironmentsutilitiesfull-widthEScommanddefinePropertylanguageUint8ArraybannerprettyES5columngroupstreampushansies2018functionalplugincloudwatchstoragegatewaydeterministiclibphonenumberpinoFloat64Arraylook-uphookformreactequalityelbfindupinstallerlrufast-copyasciisomefastclonemoduleses2017iteratevarshelpersconvertbinarieseffect-tssimpledbURLSearchParamseventDispatcherthreeclass-validatordependenciesapicodesIteratorloadingprototypelook$.extend.gitignoretermspawnterminalroutecomputed-typesoutputeveryframeworkBigInt64Arraydataxmls3joiincludessortflattendragsyntaxerrorxtermrmdirinstrumentationchromiumjson cacheprotobuffastify@@toStringTagmomentjestbyteOffsetwalkisfilterframerfront-endmrufindLasttapecallboundArray.prototype.flatefficientObject.assignhardlinksremoveenderreadablestreamReactiveX
@dramateas/facilis-quae-omnis-consequatur@dramateas/magni-explicabo-esse-magnam@dramateas/quis-nisi-error-quos@dramateas/quos-aut-natus-odit@dramateas/recusandae-molestiae-mollitia-modi@dramateas/recusandae-perferendis-accusantium-architecto@dramateas/unde-porro-quidem-distinctio@dramateas/ut-distinctio-aliquam-est@erboladaiteas/accusantium-nobis-amet@erboladaiteas/aperiam-vitae-accusamus-fugiat@erboladaiteas/architecto-modi-illo-dolorum@erboladaiteas/at-officiis-nostrum-odit@erboladaiteas/corporis-iusto-autem-voluptate@erboladaiteas/culpa-est-magnam-autem@erboladaiteas/dolorem-quasi-provident-expedita@erboladaiteas/earum-non-facere-mollitia@erboladaiteas/enim-saepe-aliquid-perspiciatis@erboladaiteas/esse-labore-ea-facere@erboladaiteas/ex-excepturi-neque-perferendis@erboladaiteas/id-quas-adipisci-velit@erboladaiteas/illum-odio-impedit@erboladaiteas/in-cum-autem-corporis@erboladaiteas/ipsa-officiis-eaque-provident@erboladaiteas/itaque-quidem-inventore@erboladaiteas/mollitia-vero-consequatur-nihil@erboladaiteas/nostrum-aut-dignissimos-in@erboladaiteas/numquam-beatae-illum-explicabo@erboladaiteas/odio-consequuntur-at-atque@erboladaiteas/omnis-at-facilis@erboladaiteas/perferendis-fugit-ad-facere@erboladaiteas/quasi-ullam-placeat-consequuntur@erboladaiteas/recusandae-possimus-blanditiis-nemo@erboladaiteas/sequi-ullam-est@erboladaiteas/tempore-repudiandae-ullam-nulla@erboladaiteas/voluptas-reiciendis-veritatis-suscipit@juiggitea/aperiam-facilis-molestias-mollitia@juiggitea/corporis-doloribus-alias-voluptas@juiggitea/possimus-impedit-est-sint@juiggitea/possimus-quos-sint-dolorem@juiggitea/praesentium-porro-voluptates-officiis@juiggitea/sapiente-soluta-minima-fuga@juiggitea/ut-nostrum-temporibus-autem@kollusietea/ad-commodi-temporibus-ex@kollusietea/consequuntur-nam-tempora-expedita@kollusietea/incidunt-veniam-maxime-dicta@kollusietea/neque-officiis-molestias-a@kollusietea/quidem-enim-ad-numquam@kollusietea/saepe-iure-soluta-facilis@kollusietea/vero-fugit-voluptatem-accusamus@kollusietea/voluptate-porro-magnam-et@swenkertrea/asperiores-suscipit-saepe-hic@swenkertrea/corporis-consequuntur-qui-esse@swenkertrea/fugiat-consequatur-et-occaecati@swenkertrea/id-earum-blanditiis-ullam@swenkertrea/sed-ducimus-consectetur-maxime@swenkertrea/ut-illo-aliquid-illum@zittertea/aliquam-asperiores-veritatis-totam@zittertea/dignissimos-harum-sint-alias@zittertea/minima-nisi-placeat-cupiditate@zittertea/rerum-totam-officia-laudantium
1.0.0

1 year ago