Node module using requirejs and typescript - javascript

I use requirejs and typescript for a node_module.
https://github.com/Ayolan/validator-extended/blob/master/app.js
It works but I cannot load it once installed from npm.
It looks like the requirejs config on the node_module change the config of my project (baseUrl and nodeRequire config actually).
There is a way to use TS and requirejs on a node_module?

Node.js does not use the AMD specification for JavaScript modules but instead the CommonJS modules. You'll need to tell the TypeScript compiler to compile your modules to this specification. This can be easily achieved by passing in the --module "commonjs"flag to the compiler.
Please note, that although the CommonJS spec uses the require keyword, this is something completely different than RequireJS. Node.js does not rely on RequireJS for it's module loading, it has its own module loader that is based on the CommonJS spec.
In short: try to avoid using RequireJS and node.js.

His question makes sense. Using requirejs in node has a number of advantages over the standard commonjs: http://requirejs.org/docs/node.html
How to build node modules with AMD / Requirejs:
http://requirejs.org/docs/node.html#nodeModules

If you don't need requirejs AND node at the same time
That was my case when I had 2 separated typescript builds, one for the front and one for the back but I had only one package.json to put all the "#types" in so tsc would pick both .d.ts in node_modules/#types
You can just manually tell tscto take certain types with the type option:
types: [ "requirejs" ] for the front and types: [ "node" ] for the back
Hope this helps.

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.

How to transpile node_module dependencies coming as ES module?

A dependency package that I'm using only has module and main as entry points. By default, the webpack version I'm using resolves to module entry point first. If I set resolve.mainFields to main in webpack configuration, I might affect other dependencies that were being resolved by 'browser' entry point by default.
So, the question is, how can I transpile a dependency like that and have it bundled in my bundle in ES5?
Some package writers distributes their ES6 sources, some other don't.
If you can figure out what "modern JavaScript syntax" the dependency is using, In general, the standard format for distributing a module is called CJS or Common JS.
If the author of the package you are trying to use did not export CJS from it's bundle (in 99% they do), then you don't need to transpile anything.
What do you mean by "the other ones"?
Be sure to import the right sources.

Module system vs module format

I'm approaching modules for the very first time and I'm a little bit confused.
I read from various docs that there are several modules systems, like commonjs (sync), and requirejs (AMD). From ES6 plain javascript has its own module sys, which is based on commonjs.
Then I started studying webpack, that resolves dependency using commonjs or requirejs module formats, and from here starts my confusion: as far as I understand, those two are module systems, they are designed to resolve the dependencies tree on its own; it's their purpose.
What is the sense to use the commonjs/requirejs format (aka syntax) and then implement webpack to resolve the graph?
CommonJS and AMD are both runtime module systems. Webpack is compiling your code, so you're not using it to resolve the graph specifically, you're using to create a build of an application from source files. To accomplish that, webpack 'understands' both types of modules so that it can analyze your code, identify dependencies, and bundle and optimize appropriately.
Webpack supports things that the original module systems don't: you can use more dynamic expressions to represent the module you're requiring; you can extend the require resolution behavior itself; you can specify an asynchronous runtime loading using its require.ensure syntax. Webpack's author could have defined a new module system to support these additional features, but then you'd have to rewrite all your existing source (and any third party modules) to accommodate the build tool. Instead, webpack is good about supporting whatever modules you already use, and giving you additional tools to handle more complex build needs.

How to browserify a browserified module?

The title seems confusing but I'll give an example.
Let's say I create a module that uses ES6 that runs in the browser, so I use browserify with babelify to build everything.
Now I want to include that same module in a project that uses browserify, but does not uses Babel to compile ES6, so I need the compiled version.
I tried to require the "browserified" module like this:
// es5-project.js
require('./compiled-module-with-browserify');
But when I run browserify es5-project.js I start to get some errors like this:
Error: Cannot find module './XXX' from '/Users/mauricio.oliveira/projects/project-name/dist-folder'
And that makes sense, since browserify compiled all modules into one file, it won't find the modules inside the compiled file.
Does anyone have faced a problem like this one? if you did, how you solved it?
Thanks!
Found the answer!
This will do the trick https://github.com/substack/browserify-handbook#browser-field
Just define a "browser" index in the package.json file, and point to the initial source file.
:)

Are there tools for compiling CommonJS modules into a single .js file?

Are there any tools that can compile modules written with CommonJS/Node-like modules (require, exports, etc.) into a single .js file to be served to a browser?
Sounds like you're looking for Browserify:
https://github.com/substack/node-browserify
"Make node-style require() work in the browser with a server-side build
step, as if by magic!"
Another quite similar utility named CommonJS Compiler and Grunt task respectively you can find at https://github.com/dsheiko/cjsc
It uses Esprima syntaxTree while parsing require() calls in the modules. It enclosures each module in a unique scope and does the caching in the very way nodejs does. It works fine with UMD (universal module definition) modules. What I like most, it adds during compiling very little of code - small require function body plus define-call wrapper per module.
If you want something you can use directly from PHP, try cjsDelivery.

Categories