Is there any way to convert a Node project to Deno? - javascript

I want to convert a Node.js project to Deno. Is there any guide available?
My current project has lots of NPM files and it's already in TypeScript.
Any tips?

Deno and Node.js APIs are not compatible, of course you will be able to reuse all javascript/typescript code but you'll need to refactor or add polyfills.
To ease migration Deno provides a Node Compatibility library, std/node, which still needs a lot of work.
Fortunately require is one of the already supported polyfills
import { createRequire } from "https://deno.land/std/node/module.ts";
const require = createRequire(import.meta.url);
// Loads native module polyfill.
const path = require("path");
// Visits node_modules.
const leftPad = require("left-pad");
console.log(leftPad('5', 5, '0'))
If you run that example:
npm i left-pad
deno run --allow-read node.js
// 00005
As you can see left-pad was loaded correctly from node_modules/. So for NPM packages that do not rely on Node.js API, you can easily require them using std/node.
Here's a list of all supported modules
Right now, for the packages that rely heavily on Node.js API, the best thing you can do is rewrite them using Deno API.
As the project matures there will be easier ways to convert a Node.js project to Deno.
IMO for big projects working perfectly on Node.js it's not worth it to migrate them. Deno & Node.js can live together it's not one or the other. Build new projects on Deno if you prefer instead of migrating old ones.

Check out Denoify, it's a build tool that does what you want. You don't have to write the port the tool do it for you, it is all detailed in the docs.
Disclosure: I am the author.

Starting from Deno v1.15 there is Node.js compatibility mode which is unstable and comes with some caveats. There is also an issue in the repo tracking the progress of the Node Compat mode.
Quoting from the docs
Node.js compability mode
Starting with v1.15 Deno provides Node compatiblity mode that makes it
possible to run a subset of programs authored for Node.js directly in
Deno. Compatiblity mode can be activated by passing --compat flag in
CLI.
⚠️ Using compatiblity mode currently requires the --unstable flag. If
you intend to use CJS modules, the --allow-read flag is needed as
well.
⚠️ Package management is currently out of scope for Node.js
compatiblity mode. For the time being we suggest to keep using your
current solution (npm, yarn, pnpm).
Please checkout the docs for
Example
How it works?
Module Resolution
Node.js built-in modules
Typescript support

denoify demo:
#! /bin/sh
cd $(mktemp -d)
npm init -y
sed -i 's|"main": "index.js"|"main": "src/index.ts"|' package.json
mkdir src
cat >src/index.ts <<'EOF'
import { writeSync } from 'fs'
writeSync(1, "hello world\n")
EOF
echo '{"compilerOptions": { "outDir": "out" }}' >tsconfig.json
npm install denoify
npx denoify
deno run --allow-env=NODE_DEBUG deno_out/index.ts
input: src/index.ts
import { writeSync } from 'fs'
writeSync(1, "hello world\n")
output: deno_out/index.ts
import { writeSync } from 'https://deno.land/std#0.159.0/node/fs.ts'
writeSync(1, "hello world\n")

Related

Importing in Node.js: error "Must use import to load ES Module" [duplicate]

This question already has answers here:
SyntaxError: Cannot use import statement outside a module
(34 answers)
Closed last year.
I'm trying to import myArr from hello.js into index.js. However I get an error of
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module
File hello.js
export let myArr = ['hello', 'hi', 'hey'];
File index.js
import { myArr } from './hello.js';
console.log(myArr);
Where am I going wrong?
Use version 2:
npm install node-fetch#2
node-fetch from v3 is an ESM-only module - you are not able to import it with require().
If you cannot switch to ESM, please use v2 which remains compatible with CommonJS. Critical bug fixes will continue to be published for v2.
I ran your code without any problems. Check for two things:
Node.js version >= 14. It only works with the latest version of Node.js.
Make sure your package.json includes a line for "type": "module". Without this line, Node.js assumes you want to use CommonJS modules rather than ESM.
I ran into a similar issue while building my React project.
Here's the error:
ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/pradeep/Work/my_project/node_modules/#babel/runtime/helpers/interopRequireWildcard/_index.mjs
Then I realized that I am on a different Node.js version than the one used to install packages in this project.
I had two options:
Change Node.js version to the one required by this project and build again.
Stay on the Node.js version you have and remove the node_modules directory and package-lock.json file and do npm install again.
I chose the first approach and it worked for me.
If you have Node.js version lower than 14, e.g., v12 - you must specify this flag:
node --experimental-modules your.mjs
I use nvm to install the latest stable version of Node.js.
To delete the package-lock.json file and the node_modules folder, run npm. I then npm start to solve my problem.
Rename hello.js to hello.mjs.
You are using CommonJS right now with the .js extension. To import ES6 modules, you will have to change the extension of the file that you want to import to .mjs so it knows that it is an ES6 module.
The problem is that Node.js does not currently support import and export natively yet. It is still experimental according to the documentation. I recommend you use Babel to compile your code and allow you to use import and export.
For example, you can install the #babel/node package and run your project using:
npx babel-node index.js
Here are the documentation for #babel/node. Like the documentation state, this command is only meant for local development. In production, they recommend a configuration like this.

Is npm install --save ever used with webpack?

I am learning to use webpack and generally getting in to the Javascript world, including npm.
Several answers deal with --save vs --save-dev when using npm install. My understanding is that their use (and updates to package.json) is actually useful when recreating either a run or a dev environment via npm install <the package being developed or ran>
--save is used to save packages needed to run the app in node.js, that is on a server
--save-dev is used to save packages needed to develop the app
a bare npm install <module> just installs the package, without enabling the possibility to install it somewhere else though the appropriate entry in package.json
Therefore, in a webpack context, is --save ever used? I belive not, because what is created is a JS bundle which is then included in the HTML file, and ran in a browser. In that sense, there is never a need to "save modules needed to run your app".
In the same vein, --save-dev is useful (again, in a webpack context) at it allows someone to develop elsewhere (in that case both modules in the app (say, moment.js) and logistical ones (say, gulp) should be installed with --save-dev, right?)
Finally, a bare npm install <module> is also possible (although less useful) is the development is not intended to be done elsewhere (the modules are still installed but no mention of this fact is made in package.json).
Is this correct? Specifically, is the assumption of a lack of --save in a webpack context true?
Anything that it utilised in the production build of your application should be listed in save. For example if you use React, your application utilises React in the final production build. It doesn't matter that your file is bundled but the fact that it's heavily relied upon running when compiled.
Anything that is used during development should be listed under devDependency. In this example, once WebPack has finished bundling your files, we no longer care about WebPack because it's not apart of the final compiled file.
--save-dev : Anything that is used during development such as Unit testing frameworks or bundlers etc.
--save : Anything that is used within your application such as Axios, React, Vue or Chart.JS etc.

How can we trust npm modules?

I'm using many Node.js modules through npm package manager. Since these modules are not developed by trusted organisations, are they trustworthy?
I don't know whether the npm team is doing any security checks for each module submitted by developers.
NPM is not doing any checks whatsoever. They are just a registry.
The whole thing is built on the trust in the dev community and sharing.
Most node modules are open source and you can review their code in their repository (usually Github).
So that's the best way to 'trust' them.
Some node modules give you prebuilt native binaries, so that might be riskier in a way, but if it is popular (like ws for example) then I see no issue.
You can also check the NPM publisher user, which sometimes is a known company like Oracle.
The idea is to find the most popular npm modules. You can do this by checking the stars on each project.
Some tips:
Use npm to manage dependencies in your dev environment, but not in your deployment scripts.
Tools like npm are development tools. They’re a convenient way to download and update modules. They’re not deployment tools, have never been deployment tools, and should not be used for deployment!
Use npm shrinkwrap in the development repository and check in the result. This will lock your module versions in place, including sub-dependencies
More details here
Update - June 2019
In npm#6 security check is included.
You could run npm audit to recursively analyze your dependency trees to identify specifically what’s insecure
2016 version
You could use the nsp tool provided by Node Security Platform, which helps to audit all the modules from your package.json
npm install nsp --global
nsp check
There are a few programs, available from npm, that can run against your package.json and check for known vulnerabilities. Not perfect, but a great start. The one I have used is called nsp but there are others.
It is not much secure because these modules are not developed by any organizations like what php/apache have, However it is good technology and you can also use nsp modules to check the security issues in you node modles.
Yes ! Almost all node modules are open source so you can actually view code snippets running behind module. this might help you to build your trust on package you are willing to use in your application
Actually I don't use to much packages:
1) express
2) body & cookie-parser (sometimes I'm lazy to write middleware),
3) mongoose,
4) pug,
5) request,
6) async,
7) lodash,
8) string
all other stuff I write myself and put in "components" folder.
let's say most of people so lazy that do:
const md5 = require('md5');
let data = 'something';
data = md5(data);
but I do it with crypto (it's by default included in all nodejs versions):
const crypto = require('crypto');
let data = 'something';
data = crypto
.createHash('md5')
.update(data.toString())
.digest('hex');
I keep logic to not to use package:
1) if package is small (I always read package files if it's unknown for me package)
2) version is not above 1.0.0 (no warranty that will go further)
3) no recent iterations (commits) in repository
btw nsp check of my applications says: (+) No known vulnerabilities found
(:
I've made node-safe, which allows you to use the native macOS sandbox when using node, npm and yarn:
# Allow reading files, but only in the current folder
node --enable-sandbox --allow-read="./**" myscript.js
# Run npm with sandbox (can only write to `./node_modules` by default)
npm --enable-sandbox install got
When using the sandboxed package managers rogue dependencies are not able to compromise your system anymore through postinstall scripts and other means.
If you are installing a package that you do not trust, you can avoid this vulnerability by running
npm install --ignore-scripts
for more details check here
Here is an awesome blog which can give you clear picture blog

When using Meteor, should I prefix npm with meteor?

When working on Meteor 1.3 projects, should I always prefix npm with meteor? In the Meteor documentation and in code examples I see both.
I suspect that I always want to do this:
$ meteor npm install --save some-package
But is there ever a situation, in a Meteor project, where I want to just use the system npm?
$ npm install --save some-package
Are people just using shorthand when they omit the meteor prefix?
Well, to be exact, it depends on what you want to perform.
The easy rationale is based on what Tom did not explicitely say in his answer:
$ meteor npm install … will use the local npm shipped / bundled with Meteor Tools. It is the official supported version for Meteor.
$ npm install … will use your global npm, which version might differ from Meteor's one.
In the case of npm, the difference might be unnoticeable.
Unfortunately, the situation is different for Node: Meteor 1.3 still relies on Node 0.10.43! Simply give a try with commands $ meteor node --version and $ node --version.
Meteor 1.4 is supposed to upgrade to Node 4.
Knowing that, you can still use $ node (without meteor prefix), as long as your script does not need to be executed later on by Meteor itself (typically through a build process). Even if it does, you should not have troubles if your script does not use advanced Node features (i.e. introduced after version 0.10.43).
At least there is no difference in using a global npm or the meteor encapsulated. For me, I always use meteor npm or meteor node because I do not need and do not want to install global software.
Also to know, the bundled node is always the release with best tested compatibility and so I always use that. Also on production environment, we have installed meteor and use the bundled npm and node when running our apps. No issues by now.
I also like to have all project related stuff inside the project folder and not globally. That means, that we do not install anything npm related globally but always local to the node-modules folder.
This gives us the opportunity to move and run our software on different self hosting environments without headages or compatibility issues even between projects with different releases on same system.
Be aware that before release 1.3.4.3 the meteor tool does not respect always latest tools but this is solved by now.
Cheers
Tom

How do we or can we use node modules via npm with Meteor?

How do we or can we use node modules via npm with Meteor?
Or is that something that will be dependent on the packaging API?
Or is there a prescribed method that is recommended?
Meteor 1.3, released on March 28, 2016, gives apps full ES6 (ES2015) modules support and out of the box NPM support. Apps and packages can now load NPM modules directly and easily on the client and on the server.
If you can use 1.3, then check http://guide.meteor.com/using-packages.html#installing-npm.
For example, to use moment.js:
meteor npm install --save moment
Then in your code:
import moment from 'moment';
// this is equivalent to the standard node require:
const moment = require('moment');
If you need to use an older version of Meteor, read the rest of the answer below.
Pre-Meteor 1.3:
Since v0.6.0, Meteor integrates directly with NPM modules with the help of a 3rd party package. For example, to use a module like ws,
Run sudo npm install -g ws (or for local installs, see this)
In your sever JavaScript file,
var Websocket = Npm.require('ws');
var myws = new Websocket('url');
To use a core Node module, just make the corresponding Npm.require() call, e.g. var Readable = Npm.require('stream').Readable.
You can use any of the more than 230,000 NPM modules directly with Meteor thanks to the NPM package developed by Arunoda.
You can also define dependencies on Npm packages from smart packages - from the initial announcement of npm support:
Your smart package can now define dependencies directly, by adding a call to Npm.depends in package.js:
Npm.depends({
"awssum": "0.12.2",
"underscore.string": "2.3.1"
});
All of this works well with hot code reload, just like the rest of Meteor. When you make changes, the bundler will automatically download missing npm packages and re-pin its dependencies.
To use an NPM module within server code, use Npm.require as you would normally use plain require. Notably, __meteor_bootstrap__.require has been eliminated and all of its uses have been converted to Npm.require.
There is a small example of using an NPM module in your application.
Note that this answer applies to versions of Meteor prior to 0.6.0, which was released in April 2013 and added direct npm integration
Install modules as you normally would through npm and then use
var require = __meteor_bootstrap__.require,
pd = require("pd"),
after = require("after") // etc
Load any modules you want
I did a complete write-up on this on Meteorpedia:
http://www.meteorpedia.com/read/npm
The article covers how to use npm in both your app and/or packages, and common patterns for wrapping regular callbacks and event emmitter callbacks to work properly in Meteor and Fibers, and include's references to Arunoda's async-utilities and additional resources.
You could use the Meteor Npm package
meteor add meteorhacks:npm
Then create a packages.json file in your project's root directory with the NPM module's info.
{
"redis": "0.8.2",
"github": "0.1.8"
}
Then as simple as (server side)
var github = Meteor.npmRequire("github");
var redis = Meteor.npmRequire("redis");
So you just use Meteor.npmRequire instead of require
I wrote a Gist on how to do this as of Meteor 0.6.5, How to add Node.js npms to your Meteor.js project.
I am using such a script which nicely install all Node.js dependencies. It behaves similar to the official support in the Meteor engine branch (it installs dependencies at runtime), but it also supports installing from Git repositories and similar goodies.

Categories

Resources