Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(unstable): initial support for npm specifiers #15484

Merged
merged 72 commits into from
Aug 20, 2022
Merged

Conversation

dsherret
Copy link
Member

This adds initial very rough support for npm specifiers for deno run, deno eval, and deno test.

  • Packages and their registry info are downloaded & cached to the deno dir. Reloading registry info can be done by using the --reload flag.
  • Node globals are limited to the npm packages. For example, this allows for the node code to use a different setTimeout implementation.
  • No type checking, lsp, deno run npm:mkdirp, deno info, deno vendor, or lockfile support yet. These will land in separate PRs.

Maybes before landing:

  • Analyzing the "native" node modules with deno graph is incredibly slow. The need to do this should be eliminated somehow.

Co-authored-by: Bartek Iwańczuk [email protected]

@ry
Copy link
Member

ry commented Aug 18, 2022

Excluding the testdata

# git diff main --stat -- ':!cli/tests/testdata/npm/registry/'
 Cargo.lock                                        |   4 +
 cli/Cargo.toml                                    |   1 +
 cli/cache/mod.rs                                  |  17 ++++
 cli/compat/esm_resolver.rs                        |   3 +-
 cli/compat/mod.rs                                 |  41 +++------
 cli/graph_util.rs                                 |  28 +++++-
 cli/lsp/cache.rs                                  |   4 +-
 cli/lsp/diagnostics.rs                            |   3 +
 cli/main.rs                                       |   2 +-
 cli/module_loader.rs                              | 103 ++++++++++++++--------
 cli/node/analyze.rs                               | 144 ++++++++++++++++++++++++++++++
 cli/node/mod.rs                                   | 697 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 cli/npm/cache.rs                                  |  43 +++++----
 cli/npm/mod.rs                                    | 171 ++++++++++++++++++++++++++++++------
 cli/npm/registry.rs                               |  35 +++++++-
 cli/npm/resolution.rs                             |  46 +++++++---
 cli/proc_state.rs                                 | 117 +++++++++++++++++++++----
 cli/standalone.rs                                 |   1 +
 cli/tests/integration/mod.rs                      |   2 +
 cli/tests/integration/npm_tests.rs                | 123 ++++++++++++++++++++++++++
 cli/tests/testdata/commonjs/init.js               |  11 +--
 cli/tests/testdata/npm/cjs_sub_path/main.js       |  21 +++++
 cli/tests/testdata/npm/cjs_sub_path/main.out      |  16 ++++
 cli/tests/testdata/npm/cjs_with_deps/main.js      |  12 +++
 cli/tests/testdata/npm/cjs_with_deps/main.out     |  15 ++++
 cli/tests/testdata/npm/dynamic_import/main.out    |   4 +
 cli/tests/testdata/npm/dynamic_import/main.ts     |   3 +
 cli/tests/testdata/npm/dynamic_import/other.ts    |   4 +
 cli/tests/testdata/npm/esm/main.js                |   7 ++
 cli/tests/testdata/npm/esm/main.out               |   2 +
 cli/tests/testdata/npm/esm/test.js                |   5 ++
 cli/tests/testdata/npm/esm/test.out               |  12 +++
 cli/tests/testdata/npm/import_map/import_map.json |   5 ++
 cli/tests/testdata/npm/import_map/main.js         |   7 ++
 cli/tests/testdata/npm/import_map/main.out        |   2 +
 cli/worker.rs                                     | 114 ++++++++++++++++--------
 ext/node/01_node.js                               | 111 ++++++++++++++++++++++++
 ext/node/{01_require.js => 02_require.js}         | 212 +++++++++++++++++++++++++++++----------------
 ext/node/Cargo.toml                               |   2 +
 ext/node/errors.rs                                | 122 ++++++++++++++++++++++++++
 ext/node/lib.rs                                   | 380 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
 ext/node/package_json.rs                          | 158 +++++++++++++++++++++++++++++++++
 ext/node/resolution.rs                            | 696 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 runtime/build.rs                                  |   2 +-
 runtime/examples/hello_runtime.rs                 |   1 +
 runtime/web_worker.rs                             |   4 +-
 runtime/worker.rs                                 |   5 +-
 test_util/Cargo.toml                              |   1 +
 test_util/src/lib.rs                              |  72 ++++++++++++++-
 49 files changed, 3238 insertions(+), 353 deletions(-)

Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @dsherret !

I'm concerned about the deno_graph slowness, it's going to be pretty apparent to users.

cli/compat/mod.rs Show resolved Hide resolved
cli/npm/resolution.rs Outdated Show resolved Hide resolved
cli/npm/resolution.rs Show resolved Hide resolved

// add the builtin node modules to the graph data
let node_std_graph = self
.create_graph(vec![(compat::MODULE_ALL_URL.clone(), ModuleKind::Esm)])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slowness is quite bad... it takes almost 2 seconds to load a very basic npm dependency that's already been downloaded.

cli/tests/integration/npm_tests.rs Show resolved Hide resolved
cli/node/analyze.rs Outdated Show resolved Hide resolved
cli/node/analyze.rs Show resolved Hide resolved
cli/node/analyze.rs Show resolved Hide resolved
) -> Result<(), AnyError> {
let source_code = &format!(
r#"(async function loadBuiltinNodeModules(moduleAllUrl) {{
const moduleAll = await import(moduleAllUrl);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unfortunate that we have to load all of the node modules even if only some are used. Do you think in the future these could be loaded lazily?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlikely, these modules have a lot of cross-imports, so they would be loaded anyway

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd push back on that assumption. I'm sure there are many npm modules that don't require, say, crypto.

/// For all discovered reexports the analysis will be performed recursively.
///
/// If successful a source code for equivalent ES module is returned.
pub fn translate_cjs_to_esm(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be great to have a little unit test for this...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are integration tests that cover this API

cli/node/mod.rs Outdated Show resolved Hide resolved
cli/node/mod.rs Outdated Show resolved Hide resolved
ext/node/package_json.rs Show resolved Hide resolved
ext/node/package_json.rs Show resolved Hide resolved
Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dsherret dsherret merged commit 87f80ff into main Aug 20, 2022
@dsherret dsherret deleted the npm_deno_run_support branch August 20, 2022 15:31
@dsherret dsherret mentioned this pull request Aug 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants