diff options
Diffstat (limited to 'docs/npm_nodejs')
-rw-r--r-- | docs/npm_nodejs/cdns.md | 186 | ||||
-rw-r--r-- | docs/npm_nodejs/faqs.md | 55 | ||||
-rw-r--r-- | docs/npm_nodejs/import_maps.md | 112 | ||||
-rw-r--r-- | docs/npm_nodejs/std_node.md | 100 |
4 files changed, 0 insertions, 453 deletions
diff --git a/docs/npm_nodejs/cdns.md b/docs/npm_nodejs/cdns.md deleted file mode 100644 index 36b26199f..000000000 --- a/docs/npm_nodejs/cdns.md +++ /dev/null @@ -1,186 +0,0 @@ -## Packages from CDNs - -Because Deno supports remote HTTP modules, and content delivery networks (CDNs) -can be powerful tools to transform code, the combination allows an easy way to -access code in the npm registry via Deno, usually in a way that works with Deno -without any further actions, and often enriched with TypeScript types. In this -section we will explore that in detail. - -### What about `deno.land/x/`? - -The [`deno.land/x/`](https://deno.land/x/) is a public registry for code, -hopefully code written specifically for Deno. It is a public registry though and -all it does is "redirect" Deno to the location where the code exists. It doesn't -transform the code in any way. There is a lot of great code on the registry, but -at the same time, there is some code that just isn't well maintained (or doesn't -work at all). If you are familiar with the npm registry, you know that as well, -there are varying degrees of quality. - -Because it simply serves up the original published source code, it doesn't -really help when trying to use code that didn't specifically consider Deno when -authored. - -### Deno "friendly" CDNs - -Deno friendly content delivery networks (CDNs) not only host packages from npm, -they provide them in a way that maximizes their integration to Deno. They -directly address some of the challenges in consuming code written for Node.js: - -- The provide packages and modules in the ES Module format, irrespective of how - they are published on npm. -- They resolve all the dependencies as the modules are served, meaning that all - the Node.js specific module resolution logic is handled by the CDN. -- Often, they inform Deno of type definitions for a package, meaning that Deno - can use them to type check your code and provide a better development - experience. -- The CDNs also "polyfill" the built-in Node.js modules, making a lot of code - that leverages the built-in Node.js modules _just work_. -- The CDNs deal with all the semver matching for packages that a package manager - like `npm` would be required for a Node.js application, meaning you as a - developer can express your 3rd party dependency versioning as part of the URL - you use to import the package. - -#### esm.sh - -[esm.sh](https://esm.sh/) is a CDN that was specifically designed for Deno, -though addressing the concerns for Deno also makes it a general purpose CDN for -accessing npm packages as ES Module bundles. esm.sh uses -[esbuild](https://esbuild.github.io/) to take an arbitrary npm package and -ensure that it is consumable as an ES Module. In many cases you can just import -the npm package into your Deno application: - -```ts -import React from "https://esm.sh/react"; - -export default class A extends React.Component { - render() { - return ( - <div></div> - ); - } -} -``` - -esm.sh supports the use of both specific versions of packages, as well as -[semver](https://semver.npmjs.com/) versions of packages, so you can express -your dependency in a similar way you would in a `package.json` file when you -import it. For example, to get a specific version of a package: - -```ts -import React from "https://esm.sh/react@17.0.2"; -``` - -Or to get the latest patch release of a minor release: - -```ts -import React from "https://esm.sh/react@~16.13.0"; -``` - -esm.sh uses the `std/node` polyfills to replace the built-in modules in Node.js, -meaning that code that uses those built-in modules will have the same -limitations and caveats as those modules in `std/node`. - -esm.sh also automatically sets a header which Deno recognizes that allows Deno -to be able to retrieve type definitions for the package/module. See -[Using `X-TypeScript-Types` header](../typescript/types.md#using-x-typescript-types-header) -in this manual for more details on how this works. - -The CDN is also a good choice for people who develop in mainland China, as the -hosting of the CDN is specifically designed to work with "the great firewall of -China", as well as esm.sh provides information on self hosting the CDN as well. - -Check out the [esm.sh homepage](https://esm.sh/) for more detailed information -on how the CDN can be used and what features it has. - -#### Skypack - -[Skypack.dev](https://www.skypack.dev/) is designed to make development overall -easier by not requiring packages to be installed locally, even for Node.js -development, and to make it easy to create web and Deno applications that -leverage code from the npm registry. - -Skypack has a great way of discovering packages in the npm registry, by -providing a lot of contextual information about the package, as well as a -"scoring" system to try to help determine if the package follows best-practices. - -Skypack detects Deno's user agent when requests for modules are received and -ensures the code served up is tailored to meet the needs of Deno. The easiest -way to load a package is to use the -[lookup URL](https://docs.skypack.dev/skypack-cdn/api-reference/lookup-urls) for -the package: - -```ts -import React from "https://cdn.skypack.dev/react"; - -export default class A extends React.Component { - render() { - return ( - <div></div> - ); - } -} -``` - -Lookup URLs can also contain the [semver](https://semver.npmjs.com/) version in -the URL: - -```ts -import React from "https://cdn.skypack.dev/react@~16.13.0"; -``` - -By default, Skypack does not set the types header on packages. In order to have -the types header set, which is automatically recognized by Deno, you have to -append `?dts` to the URL for that package: - -```ts -import { pathToRegexp } from "https://cdn.skypack.dev/path-to-regexp?dts"; - -const re = pathToRegexp("/path/:id"); -``` - -See -[Using `X-TypeScript-Types` header](../typescript/types.md#using-x-typescript-types-header) -in this manual for more details on how this works. - -Skypack docs have a -[specific page on usage with Deno](https://docs.skypack.dev/skypack-cdn/code/deno) -for more information. - -### Other CDNs - -There are a couple of other CDNs worth mentioning. - -#### UNPKG - -[UNPKG](https://unpkg.com/) is the most well known CDN for npm packages. For -packages that include an ES Module distribution for things like the browsers, -many of them can be used directly off of UNPKG. That being said, everything -available on UNPKG is available on more Deno friendly CDNs. - -#### JSPM - -The [jspm.io](https://jspm.io) CDN is specifically designed to provide npm and -other registry packages as ES Modules in a way that works well with import maps. -While it doesn't currently cater to Deno, the fact that Deno can utilize import -maps, allows you to use the [JSPM.io generator](https://generator.jspm.io/) to -generate an import-map of all the packages you want to use and have them served -up from the CDN. - -### Considerations - -While CDNs can make it easy to allow Deno to consume packages and modules from -the npm registry, there can still be some things to consider: - -- Deno does not (and will not) support Node.js plugins. If the package requires - a native plugin, it won't work under Deno. -- Dependency management can always be a bit of a challenge and a CDN can make it - a bit more obfuscated what dependencies are there. You can always use - `deno info` with the module or URL to get a full breakdown of how Deno - resolves all the code. -- While the Deno friendly CDNs try their best to serve up types with the code - for consumption with Deno, lots of types for packages conflict with other - packages and/or don't consider Deno, which means you can often get strange - diagnostic message when type checking code imported from these CDNs, though - skipping type checking will result in the code working perfectly fine. This is - a fairly complex topic and is covered in the - [Types and type declarations](../typescript/types.md) section of the manual. diff --git a/docs/npm_nodejs/faqs.md b/docs/npm_nodejs/faqs.md deleted file mode 100644 index cde1c593a..000000000 --- a/docs/npm_nodejs/faqs.md +++ /dev/null @@ -1,55 +0,0 @@ -## Frequently asked questions - -### Getting errors when type checking like `cannot find namespace NodeJS` - -One of the modules you are using has type definitions that depend upon the -NodeJS global namespace, but those types don't include the NodeJS global -namespace in their types. - -The quickest fix is to skip type checking. You can do this by using the -`--no-check` flag. - -Skipping type checking might not be acceptable though. You could try to load the -Node.js types yourself. For example from UNPKG it would look something like -this: - -```ts -import type {} from "https://unpkg.com/@types/node/index.d.ts"; -``` - -Or from esm.sh: - -```ts -import type {} from "https://esm.sh/@types/node/index.d.ts"; -``` - -Or from Skypack: - -```ts -import type {} from "https://cdn.skypack.dev/@types/node/index.d.ts"; -``` - -You could also try to provide only specifically what the 3rd party package is -missing. For example the package `@aws-sdk/client-dynamodb` has a dependency on -the `NodeJS.ProcessEnv` type in its type definitions. In one of the modules of -your project that imports it as a dependency, you could put something like this -in there which will solve the problem: - -```ts -declare global { - namespace NodeJS { - type ProcessEnv = Record<string, string>; - } -} -``` - -### Getting type errors like cannot find `document` or `HTMLElement` - -The library you are using has dependencies on the DOM. This is common for -packages that are designed to run in a browser as well as server-side. By -default, Deno only includes the libraries that are directly supported. Assuming -the package properly identifies what environment it is running in at runtime it -is "safe" to use the DOM libraries to type check the code. For more information -on this, check out the -[Targeting Deno and the Browser](../typescript/configuration.md#targeting-deno-and-the-browser) -section of the manual. diff --git a/docs/npm_nodejs/import_maps.md b/docs/npm_nodejs/import_maps.md deleted file mode 100644 index ec78d6c11..000000000 --- a/docs/npm_nodejs/import_maps.md +++ /dev/null @@ -1,112 +0,0 @@ -## Using import maps - -Deno supports [import maps](../linking_to_external_code/import_maps.md) which -allow you to supply Deno with information about how to resolve modules that -overrides the default behavior. Import maps are a web platform standard that is -increasingly being included natively in browsers. They are specifically useful -with adapting Node.js code to work well with Deno, as you can use import maps to -map "bare" specifiers to a specific module. - -When coupled with Deno friendly [CDNs](./cdns.md) import maps can be a powerful -tool in managing code and dependencies without need of a package management -tool. - -### Bare and extension-less specifiers - -Deno will only load a fully qualified module, including the extension. The -import specifier needs to either be relative or absolute. Specifiers that are -neither relative or absolute are often called "bare" specifiers. For example -`"./lodash/index.js"` is a relative specifier and -`https://cdn.skypack.dev/lodash` is an absolute specifier. Where is `"lodash"` -would be a bare specifier. - -Also Deno requires that for local modules, the module to load is fully -resolve-able. When an extension is not present, Deno would have to "guess" what -the author intended to be loaded. For example does `"./lodash"` mean -`./lodash.js`, `./lodash.ts`, `./lodash.tsx`, `./lodash.jsx`, -`./lodash/index.js`, `./lodash/index.ts`, `./lodash/index.jsx`, or -`./lodash/index.tsx`? - -When dealing with remote modules, Deno allows the CDN/web server define whatever -semantics around resolution the server wants to define. It just treats a URL, -including its query string, as a "unique" module that can be loaded. It expects -the CDN/web server to provide it with a valid media/content type to instruct -Deno how to handle the file. More information on how media types impact how Deno -handles modules can be found in the -[Determining the type of file](../typescript/overview.md#determining-the-type-of-file) -section of the manual. - -Node.js does have defined semantics for resolving specifiers, but they are -complex, assume unfettered access to the local file system to query it. Deno has -chosen not to go down that path. - -But, import maps can be used to provide some of the ease of the developer -experience if you wish to use bare specifiers. For example, if we want to do the -following in our code: - -```ts -import lodash from "lodash"; -``` - -We can accomplish this using an import map, and we don't even have to install -the `lodash` package locally. We would want to create a JSON file (for example -**import_map.json**) with the following: - -```json -{ - "imports": { - "lodash": "https://cdn.skypack.dev/lodash" - } -} -``` - -And we would run our program like: - -``` -> deno run --import-map ./import_map.json example.ts -``` - -If you wanted to manage the versions in the import map, you could do this as -well. For example if you were using Skypack CDN, you can used a -[pinned URL](https://docs.skypack.dev/skypack-cdn/api-reference/pinned-urls-optimized) -for the dependency in your import map. For example, to pin to lodash version -4.17.21 (and minified production ready version), you would do this: - -```json -{ - "imports": { - "lodash": "https://cdn.skypack.dev/pin/lodash@v4.17.21-K6GEbP02mWFnLA45zAmi/mode=imports,min/optimized/lodash.js" - } -} -``` - -### Overriding imports - -The other situation where import maps can be very useful is the situation where -you have tried your best to make something work, but have failed. For example -you are using an npm package which has a dependency on some code that just -doesn't work under Deno, and you want to substitute another module that -"polyfills" the incompatible APIs. - -For example, let's say we have a package that is using a version of the built in -`"fs"` module that we have a local module we want to replace it with when it -tries to import it, but we want other code we are loading to use the standard -library replacement module for `"fs"`. We would want to create an import map -that looked something like this: - -```ts -{ - "imports": { - "fs": "https://deno.land/std@$STD_VERSION/node/fs.ts" - }, - "scopes": { - "https://deno.land/x/example": { - "fs": "./patched/fs.ts" - } - } -} -``` - -Import maps can be very powerful, check out the official -[standards README](https://github.com/WICG/import-maps#the-import-map) for more -information. diff --git a/docs/npm_nodejs/std_node.md b/docs/npm_nodejs/std_node.md deleted file mode 100644 index 38327121c..000000000 --- a/docs/npm_nodejs/std_node.md +++ /dev/null @@ -1,100 +0,0 @@ -## The `std/node` library - -The `std/node` part of the Deno standard library is a Node.js compatibility -layer. It's primary focus is providing "polyfills" for Node.js's -[built-in modules](https://github.com/denoland/deno_std/tree/main/node#supported-builtins). -It also provides a mechanism for loading CommonJS modules into Deno. - -The library is most useful when trying to use your own or private code that was -written for Node.js. If you are trying to consume public npm packages, you are -likely to get a better result using a [CDN](./cdns.md). - -### Node.js built-in modules - -The standard library provides several "replacement" modules for Node.js built-in -modules. These either replicate the functionality of the built-in or they call -the Deno native APIs, returning an interface that is compatible with Node.js. - -The standard library provides modules for the the following built-ins: - -- [`assert`](https://doc.deno.land/https/deno.land/std/node/assert.ts) - (_partly_) -- [`buffer`](https://doc.deno.land/https/deno.land/std/node/buffer.ts) -- [`child_process`](https://doc.deno.land/https/deno.land/std/node/child_process.ts) - (_partly_) -- [`console`](https://doc.deno.land/https/deno.land/std/node/console.ts) - (_partly_) -- [`constants`](https://doc.deno.land/https/deno.land/std/node/constants.ts) - (_partly_) -- [`crypto`](https://doc.deno.land/https/deno.land/std/node/crypto.ts) - (_partly_) -- [`events`](https://doc.deno.land/https/deno.land/std/node/events.ts) -- [`fs`](https://doc.deno.land/https/deno.land/std/node/fs.ts) (_partly_) -- [`module`](https://doc.deno.land/https/deno.land/std/node/module.ts) -- [`os`](https://doc.deno.land/https/deno.land/std/node/os.ts) (_partly_) -- [`path`](https://doc.deno.land/https/deno.land/std/node/path.ts) -- [`process`](https://doc.deno.land/https/deno.land/std/node/process.ts) - (_partly_) -- [`querystring`](https://doc.deno.land/https/deno.land/std/node/querystring.ts) -- [`stream`](https://doc.deno.land/https/deno.land/std/node/stream.ts) -- [`string_decoder`](https://doc.deno.land/https/deno.land/std/node/string_decoder.ts) -- [`timers`](https://doc.deno.land/https/deno.land/std/node/timers.ts) -- [`tty`](https://doc.deno.land/https/deno.land/std/node/tty.ts) (_partly_) -- [`url`](https://doc.deno.land/https/deno.land/std/node/url.ts) -- [`util`](https://doc.deno.land/https/deno.land/std/node/util.ts) (_partly_) - -In addition, there is the -[`std/node/global.ts`](https://doc.deno.land/https/deno.land/std/node/global.ts) -module which provides some of the Node.js globals like `global`, `process`, and -`Buffer`. - -If you want documentation for any of the modules, you can simply type `deno doc` -and the URL of the module in your terminal: - -``` -> deno doc https://deno.land/std/assert.ts -``` - -### Loading CommonJS modules - -Deno only supports natively loading ES Modules, but a lot of Node.js code is -still written in the CommonJS format. As mentioned above, for public npm -packages, it is often better to use a CDN to transpile CommonJS modules to ES -Modules for consumption by Deno. Not only do you get reliable conversion plus -all the dependency resolution and management without requiring a package manager -to install the packages on your local machine, you get the advantages of being -able to share your code easier without requiring other users to setup some of -the Node.js infrastructure to consume your code with Node.js. - -That being said, the built-in Node.js module `"module"` provides a function -named `createRequire()` which allows you to create a Node.js compatible -`require()` function which can be used to load CommonJS modules, as well as use -the same resolution logic that Node.js uses when trying to load a module. -`createRequire()` will also install the Node.js globals for you. - -Example usage would look like this: - -```ts -import { createRequire } from "https://deno.land/std@$STD_VERSION/node/module.ts"; - -// import.meta.url will be the location of "this" module (like `__filename` in -// Node.js), and then serve as the root for your "package", where the -// `package.json` is expected to be, and where the `node_modules` will be used -// for resolution of packages. -const require = createRequire(import.meta.url); - -// Loads the built-in module Deno "replacement": -const path = require("path"); - -// Loads a CommonJS module (without specifying the extension): -const cjsModule = require("./my_mod"); - -// Uses Node.js resolution in `node_modules` to load the package/module. The -// package would need to be installed locally via a package management tool -// like npm: -const leftPad = require("left-pad"); -``` - -When modules are loaded via the created `require()`, they are executed in a -context which is similar to a Node.js context, which means that a lot of code -written targeting Node.js will work. |