DEV Community

Pacharapol Withayasakpunt
Pacharapol Withayasakpunt

Posted on

Laziest way to publish for both NPM and <script src="">

But it is slightly harder for TypeScript's tsc.

Actually, the real problem here is loading other JavaScript files in Node via require is always sync, but requesting other files (including JavaScript files) in web browser is always async.

So, here comes a laziest way <script type="module">, i.e. import syntax.

You can see a demo here -- https://patarapolw.github.io/any-serialize/.

This package comes for being solved of this topic.

For web browsers

For web browsers, module resolution is by default relative, unless you put the full https:// url, so you cannot get node_modules folder.

A solution? Use unpkg?module. I have heard about snowpack and pika.dev too. Might be another solution to use NPM / node_modules packages.

I recently ran into a problem with unpkg?module, though -- Rate limit exceeded...

For Node with standard JavaScript

You will need either esm or Node 12+ to be able to run import by default. (Well, yeah. I use Node 10 + TypeScript, so I always have to -r esm.)

Also, you had better add "type": "module" to package.json.

For Node with TypeScript

To run in Node, if your Node doesn't support import, you will have to -r esm, including ts-node and ts-mocha.

To compile with tsc to JavaScript for web browsers, you have to add .js to all imports and exports. This is a known issue in TypeScript.

glob('dist/**/*.js', (err, matches) => {
  matches.map((m) => {
    const s = fs.readFileSync(m, 'utf8').replace(
      /(?<start>^|\n)(?<pre>(?:im|ex)port .+)(?<bracket>['"])(?<name>.+?)(?<ext>\.[tj]?s)?(?:\k<bracket>)/g,
      '$<start>$<pre>$<bracket>$<name>.js$<bracket>'
    )
    fs.writeFileSync(..., s)
  })
})
Enter fullscreen mode Exit fullscreen mode

For Deno

Deno already use import by default, but my concern is using NPM packages. There has been a talk on this too. -- https://github.com/denoland/deno/issues/1397

Bonus

I also have got one or two more bonuses.

  • Code transparency + Minimal obfuscation (because you cannot hide client-side JavaScript source code, anyway.)
  • No more global scope polluting. <script type="module"> never litter global scope, unless directly you attach to window object

Top comments (0)