Configuration for RequireJS to consult node_modules? - javascript

i'm authoring some modules for npm in umd format -- they're for node and the browser
i'm using requirejs to load the modules clientside to work on them
but requirejs can't find modules within node_modules -- getting 404's for the module identifiers at the web root
what configuration do i need to give requirejs so it will consult node_modules by default?

Related

Node 14 ECMAScript Modules and Packages

In the documentation for Node's native support of ECMAScript modules, they state
There are three types of specifiers:
...
Bare specifiers like 'some-package' or 'some-package/shuffle'. They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively. Including the file extension is only necessary for packages without an "exports" field.
...
The definition of bare specifiers indicate you can import ECMAScript Modules from "packages".
What's considered a "package" in Node.js? Does node just search the entire node_modules folder for any folder with a package.json file and consider that a package? Or is it more complicated than that? Is it the same for CommonJS modules and ESMAScript modules?
What's considered a "package" in Node.js?
In the sense of "bare" named packages for ESM, any name that matches a node builtin package, or is in node_modules/{{ bare name }} in the current directory or subsequently any parent directory, that has a package.json that loads and also has the correct name field.
Does node just search the entire node_modules folder for any folder with a package.json file and consider that a package? Or is it more complicated than that?
Basically, node doesn't care about anything you haven't named as an import though. It's always more complicated, the algorithm is documented further down on the ESM modules page.
Is it the same for CommonJS modules and ESMAScript modules?
No, although the part that resolves the package exports is shared once a "package" is located and vetted by the ESM or CommonJS rules). Big differences are
Global node_modules are not considered in ESM (i.e. traversing $NODE_PATH, $HOME and the node $PREFIX).
Outside of the process for loading this subset or "bare names" there are more differences.
ESM modules or mjs files will not load via require.
No native or JSON imports
Generally the ESM loader is a much more strict subset of CommonJS as anything Node specific doesn't apply.

Why use Webpack to bundle applications that run in node environment

For me, Webpack is a bundler for "web" since browsers don't have good support for js module system. Thus using Webpack we could still use "module" way to develop and pack them for browsers.
Webpack has a config option target
module.exports = {
target: 'node'
};
using node webpack will compile for usage in a Node.js-like environment
But NodeJS already support CommonJS modules, why need Webpack to build something that runs in NodeJS environment?
Besides, if you want to compile your javascript, for example, using the ES module, you could just use babel to do so, using es module transform plugins or proper presets.
Why use Webpack, set the target to node and then use babel loader... instead of using babel directly?
I cannot think of the use case of using Webpack to bundle application running in node.
One reason I can think of when to use webpack for node is when you have a node_modules package where it's not compiled yet (Still in ES6).
babel-node won't be able to help you bundle the node_modules packages that need to be transpiled along with the rest of your code
I had to go through this process.. ): This scenario is helpful in Yarn Workspaces where you want your server to depend on another package in your workspace. Where your server will re-update whenever you make changes in the other package with the help of webpack
How to include a few node_modules package in babel-node
Having a single server.js output
instant deployable on a server
no worry about mismatching dependencies compared to your dev environment.

are dist folders always available in node modules

i am building a tool of my own to trans compile and pack the related js files (that are written in ES6) into a bundle. so far it goes as expected with local files, but when i come to public modules, for example, react and redux etc, it's different. and i am wondering how to include these modules into the bundle? i found that there are always dist folders in most of the public modules with distributed versions residing in. so, are the dist folders always available in any module directory?
Webpack uses the same module resolution as Node.js. node_modules have a package.json which has a main field, that determines which file is being imported when you import the module in your code. Additionally webpack looks for the browser or module fields in package.json and prefers them over main, if they are present. This makes it easy to publish a build that is different from the regular Node.js build (for instance to use ES modules (import/export), which are not supported by yet Node.js but by bundlers like webpack). This behaviour can be configured with the option resolve.mainFields. For an example have a look at the package.json of Redux.
None of these fields are mandatory, but at least main is supposed to be present, so you can simply import a module with:
import module from 'module';
Or with require:
const module = require('module');
Webpack automatically includes the modules you import into the bundle.
The dist directory is not any special, but it's very common to have a dist directory that contains an UMD build. Especially as Unpkg allows you to import a node module without having to publish it manually to a CDN, it uses the dist or umd by default (as described at the bottom of the homepage).

How to use a CommonJS dependency without Browserify?

I want to use a JavaScript library in a web application which is not a single-page app and does not yet use a module loader.
But the library (virtual-dom) is only published as an npm package for Browserify, and all the examples use require.
How can I use a CommonJS dependency in a client-side app that does not use Browserify or a module loader?
Easy, simply download this file here:
https://github.com/Matt-Esch/virtual-dom/blob/master/dist/virtual-dom.js
and then include it in your page:
<script src="virtual-dom.js"></script>
Now you can access it like:
virtualDom.create(...);
virtualDom.diff(...);
virtualDom.h(...);
virtualDom.patch(...);
The Browserify --standalone option uses "a window global if no module system is found".
The virtual-dom/dist directory is built with the command browserify --standalone virtual-dom index.js > dist/virtual-dom.js and can therefore be used in this way.

Use local version of node.js package

I'm digging into a node package that uses a CLI, and am trying to extend it by adding some functionality. I've cloned the repo from github, but I've also installed it via npm.
How can I use my local version, instead of the one that's been installed via npm?
Thanks!
When you install a package using npm, it just puts it into the node_modules folder in the folder where you ran it (or if you pass -g, into a global node_modules folder).
require() uses a particular search order to find modules. To get a specific version of a module to load you can take two paths:
Specify a relative path to the module: require("./path/to/myfork/of/module")
Delete the version of the module installed by npm into mode_modules and put your fork of it in there
Make sure that your fork of that module is in a "closer" node_modules folder. Node searches the node_modules in same folder as the file calling require() and then works its way up the folder hierarchy to find a module.
For more information, take a look at http://nodejs.org/docs/v0.4.11/api/modules.html

Categories