Replies: 66 comments 9 replies
-
For Deno, you don't need npm at all. Having it located somewhere on a CDN which the The biggest "problem" with dual support would be that modules have to end in the extension in Deno. Also Node.js doesn't support TypeScript directly, and doesn't support ESM (without enabling experimental modules). So you would have to have a build a version that would work frictionlessly in Node.js and have that be your distributable to npm. I'm personally not aware of anyone who has created a good build script for Deno If you are using |
Beta Was this translation helpful? Give feedback.
-
Ahhh yeah the big issue is the requirement of file extensions for deno. I like your suggestion of Regardless of how successful deno becomes, I see dual-supporting both node and deno as pretty much necessary for most library authors. Related: microsoft/TypeScript#27481 |
Beta Was this translation helpful? Give feedback.
-
@brainkim regarding the modules resolution, there is also: microsoft/TypeScript#33437 that would be more of an ideal, but getting Node.js to support it... Though Node.js is moving towards extension required modules under the experimental ES support, there would still be a need to change the extensions on the emitted code, and if TypeScript ( |
Beta Was this translation helpful? Give feedback.
-
I think for the purpose of creating "isomorphic" Deno libs and CLIs it makes sense to implement sort of Node.js polyfill for all the Deno's built-in APIs, then bundle your tool using const {Deno, TextDecoder, TextEncoder, ...} = require('deno-polyfill');
/// deno generated bundle probably it also makes sense to convert AMD modules in the original bundle to commonjs |
Beta Was this translation helpful? Give feedback.
-
allegedly this is what @YounGoat's deno package on npm is supposed to do... |
Beta Was this translation helpful? Give feedback.
-
Okay so
This is interesting, but I’m also interested in a simpler use-case where I use 0 deno builtins and 0 node builtins (pretty much vanilla typescript). |
Beta Was this translation helpful? Give feedback.
-
@brainkim Deno can consume a single JS file or ES modules if you need imports. It doesn’t know about AMD except as an output from the bundle command. (The AMD bit is really throwing people off - we should modify deno bundle to use https://github.com/denoland/deno/blob/master/deno_typescript/amd_runtime.js to execute the main module.) |
Beta Was this translation helpful? Give feedback.
-
@ry we talked about it for Bundling v2 (#2475), but it does feel like embedding the runner directly in the bundle so it is a totally self contained script is warranted and knock a few features off the v2 list. That way we can just say "it generates a standalone script" and let people forget about the implementation. I can start working on this. |
Beta Was this translation helpful? Give feedback.
-
The whole thing would be easier if |
Beta Was this translation helpful? Give feedback.
-
@tunnckoCore again, people are obsessing about something they shouldn't obsess about. 😁 UMD specifically would be useless. That is, depending on the implementation, 2 different module formats and an ability to load as a global script, but when you only need one module format that is loaded into an environment that doesn't support CommonJS for good reason. If you really want to know the reason though, it goes something like this:
So we were left with the scenarios of:
We opted for the last. The only value in the first two is to be able to say we weren't using AMD, which seems like a very odd thing to do. AMD came into being for some valid good and valid reasons, and ESM doesn't solve all of them. There are very good reasons why ESM isn't concatenatable, and I respect that, but it does mean in a lot of cases, we will be stuck with some form of bundlers in perpetuity (and likely AMD). |
Beta Was this translation helpful? Give feedback.
-
@kitsonk I would consider System.js as a bundle output as well. I think typescript supports it as an output (though last I checked support is not great and System.js can be tricky to set up), it’s more closely aligned with ESmodules, and But most of this is unrelated to this issue, which is, given a pure typescript codebase without dependencies, how do I add support for deno consumers? The two approaches would be:
|
Beta Was this translation helpful? Give feedback.
-
@brainkim , last week or two I'm thinking about the second too. Write Nodejs (js/ts), so need for deno vscode/typescript plugins. Output esm and cjs formats - e.g. import koko from 'https://unpkg.com/@tunnckocore/kokoko?module';
koko('sasas', 200);
// should error, because both arguments must be `number` I have two dummy modules, that I'm playing with: @tunnckocore/kokoko and @tunnckocore/qwqwqw check them on unpkg. The interesting thing is that UNPKG is helping us when using the |
Beta Was this translation helpful? Give feedback.
-
Ha... I already wrote to that issue, haha. Just thought about another idea that spawned after looking around the other "compat" issues and discussions, mainly triggered to look on them today because just seen that And second, the another possible idea:
** another variant of that step is to directly URL import/resolve from Deno and transform that TS to JS, BUT that way consumers of that nodejs code source may have problems if there are any significant differences or bugs or behaviors between what Deno gives, for example, for the Write mainly in Deno. And if you want to support both Browsers and Node (and Deno, hence the source) you can use a small smart CLI that can be created, nothing fancy, just a thin translation layer using @rollup so we can output whatever format we want. It's would probably be best to be written in Node.js and then bundled as single file binary. |
Beta Was this translation helpful? Give feedback.
-
I think the best course of action is just to convince typescript peeps to allow explicit file names. |
Beta Was this translation helpful? Give feedback.
-
Don't know if this is the best place to post this, but I wanted to share the pattern I came up with for running code on both node and deno. I append this to the end of a
Not up to the needs of library authors, I know, but it's useful to have such a recipe for quick scripts that might be run on either host. |
Beta Was this translation helpful? Give feedback.
-
It's not completely unreasonable to ask that today depending on what the library does, e.g is it impractical to do the same thing in JavaScript. WebAssembly is a lot simpler than dealing with whatever incarnation of NAPI we're at now. |
Beta Was this translation helpful? Give feedback.
-
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
Beta Was this translation helpful? Give feedback.
-
Not stale I guess - I think this could be converted to a GH discussion |
Beta Was this translation helpful? Give feedback.
-
I'm still a bit boggled about how little documentation there's anywhere about writing libraries for Deno, and the existence of this issue keeps reminding me about it. There's plenty about writing applications, but for libraries, the only thing I can find on deno.land is the "Add a module" button under "Third Party Modules". I just did that for |
Beta Was this translation helpful? Give feedback.
-
TLDR; design pattern for single-source to CJS/ESM/TypeScript + Deno. Being somewhat frustrated by tooling in this space, and inspired by the TypeScript is used as the fundamental source language for the module source code. Importantly, all internal module imports have fully specified relative paths (with extensions). All source mode files are written in TypeScript, with '.ts' extensions. But, all internal imports use the '.js' extension. TypeScript's resolution algorithm will find the source file correctly. Yes, this is definitely confusing, but it is the officially supported method available since at least TypeScript-v2.0. The TypeScript source is transpiled into an ESM which, with some platform abstraction, can be utilized by both NodeJS and Deno. Importantly, for Deno operation, the target transpiled ESM code must be stored back into the repository (eg, in a 'dist' folder). The platform abstraction (Platform.Adapter) contains all external dependencies and platform-specific built-in variations. Platform-dependent definitions of Platform.Adapter contain the necessary implementation code. For example, from 'os-paths': // src/platform-adapters/_base.ts
export namespace Platform {
export type Adapter = {
readonly env: { readonly get: (_: string) => string | undefined };
readonly os: { readonly homedir?: () => string; readonly tmpdir?: () => string };
readonly path: {
readonly join: (..._: readonly string[]) => string;
readonly normalize: (_: string) => string;
};
readonly process: {
readonly platform: string;
};
};
} // src/platform-adapters/node.ts
import * as os from 'os';
import * as path from 'path';
import { Platform } from './_base.js';
export const adapter: Platform.Adapter = {
env: {
get: (s) => {
return process.env[s];
},
},
os,
path,
process,
}; From working TypeScript code, an Then, when the module is imported, the // src/mod.esm.ts
import { Adapt, OSPaths } from './lib/OSPaths.js';
import { adapter } from './platform-adapters/node.js';
const default_: OSPaths = Adapt(adapter).OSPaths;
export type { OSPaths };
export default default_; After creating a module, coded in TypeScript, producing ESM-compatible code (which is not simple), the platform abstraction code and Deno implementation is a small, straight-forward changeset (from xdg-app-paths). For detailed/working examples, I've just finished converting three small modules:
To be sure, I'm not overly happy with the necessary Ultimately, all of the modules are available for use by CJS/ESM/TypeScript (via NPMjs, github repo, or jsdelivr CDN) and Deno (via 'deno.land/x', github repo, or jsdelivr CDN). See the respective repositories for further implementation details and READMEs for further usage details. Of important note, avoiding CJS/TypeScript, and coding the module just to ESM and Deno would still allow the same platform-adapter pattern but with a huge drop in dev complexity, scripting, and tooling. |
Beta Was this translation helpful? Give feedback.
-
@eemeli that isn’t necessarily related to this issue, but you can find all info in the manual, everything else is knowledge from Js and Ts |
Beta Was this translation helpful? Give feedback.
-
@ebebbington Huh, maybe I just missed it then? I'm looking for answers to the following sorts of things, if they're in the Deno manual maybe you could give me a link?
|
Beta Was this translation helpful? Give feedback.
-
There isn't a standard for creating a Deno module. JS libraries are a collection of methods, classes and objects that are made available through the user as they see fit. However well documented libraries tend to contain the following:
Import maps are not mean for libraries, but for end users. It's encouraged for library authors to use deps.ts convention or a similar approach |
Beta Was this translation helpful? Give feedback.
-
TL;DR: Another way to write and distribute your libraries for both Deno and NPM. I'm porting my isomorphic libraries to Deno. I'm not using Deno in production myself or expect many of the users to do so, but Deno's built-in toolchain simplifies development/maintenance a lot and I like the opinionated approach Deno takes in it. Imports with extensions did cause some head-scratching, after reading this thread and trying various approaches I ended up using |
Beta Was this translation helpful? Give feedback.
-
We've started work on a Deno to npm package build tool. The hope is you add a single Deno script to your Deno-first repo and it will build an npm package from your Deno code (ESM and CommonJS), type check, and run your Deno tests in Node. From there you should just have to cd into the output directory and It's still early days, but I would appreciate if you try it out, throughly inspect its output, and see what problems or challenges you run into so we can fix them: https://github.com/denoland/dnt |
Beta Was this translation helpful? Give feedback.
-
Just checked it out, looks great, the only significant problem is missing source maps. As a side note, while I appreciate the ambition and ergonomics behind dnt's production of an NPM package in a single command, I would be happy just to have an option for |
Beta Was this translation helpful? Give feedback.
-
Since we started using |
Beta Was this translation helpful? Give feedback.
-
Is there plan to ship dnt with the deno binary? |
Beta Was this translation helpful? Give feedback.
-
@brainkim, I think you should try https://jsr.io |
Beta Was this translation helpful? Give feedback.
-
Let’s say that I have a library which is published on npm. If that library
what is the best way to add support for deno? Is there a good example repository which does this?
Additionally, if I have library which depends only on modules which dual support both node and deno, does this story change?
Related: #2644
Beta Was this translation helpful? Give feedback.
All reactions