Inspired by preact's "no build tools route", I recently created a project with no build or bundling process. Conceptually, it looks like this (pseudo code following).
I have a dependency on react-button
which uses e.g. microbundle
to resolve the preact
import through the node_modules
folder.
// dependency 1: "preact-button" npm package (uses bundler)
import { h, Component, render } from 'preact';
const button = h('button', null, 'Click');
export default Button;
Then, there's my app which requires preact-button
as a dependency. It's just a .html
file for now.
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>SO App</title>
<script type="module">
import { h, Component, render } from 'https://unpkg.com/preact?module';
import Button from "https://fantasycdn.com/preact-button?module"
</script>
</head>
<body>
</body>
</html>
However, my app is not using any bundler and hence imports preact-button
's code. If I had a bundler, this wouldn't be a problem, as the import ... from "preact"
would be resolved through the bundler. But now, taking advantage of the type="module"
syntax, this global module name cannot be imported anymore. Instead, an error is thrown:
react-button.js:
Uncaught TypeError: Error resolving module specifier “preact”. Relative module specifiers must start with “./”, “../” or “/”.
As the author of preact-button
, what I want though is that my module:
Since preact advertises this approach on their website, I took a quick look into their build process. They have a simple advantage, which is that they don't have to deal with any kind of dependencies (e.g. peer or regular), as they simply don't have any.
But is it possible to mix bundled modules and JavaScript modules without any heavy build process? Is there maybe even a commonly agreed upon approach?
A module in JavaScript is just a file containing related code. In JavaScript, we use the import and export keywords to share and receive functionalities respectively across different modules. The export keyword is used to make a variable, function, class or object accessible to other modules.
With CommonJS, each JavaScript file stores modules in its own unique module context (just like wrapping it in a closure). In this scope, we use the module. exports object to expose modules, and require to import them.
There are two types of module imports: Named Imports. Default Imports.
Until 2015, the JavaScript language had no built-in module system. Yet people had been building large systems in JavaScript for more than a decade, and they needed modules. So they designed their own module systems on top of the language.
Notice that UNPKG claims:
?module
Expands all “bare” import specifiers in JavaScript modules to unpkg URLs. This feature is very experimental
This means that your build would be transformed and cached courtesy of UNPKG into:
import { h, Component, render } from 'https://unpkg.com/preact@^10.4.6?module';
const button = h('button', null, 'Click');
export default Button;
As a confirmation of this claim, I checked how ?module
handles one of my bundled libraries on UNPKG, and it transforms:
import { Parser, Grammar } from 'nearley';
import moo from 'moo';
into:
import { Parser, Grammar } from "https://unpkg.com/nearley@^2.19.1?module";
import moo from "https://unpkg.com/moo@^0.5.1?module";
Assuming that your preact-button
module is published on npm, the current usage of bare import specifiers in your code should not be an issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With