Deno: Lodash - Uncaught Error: Protocol has to be file://

Created on 10 Feb 2020  Â·  13Comments  Â·  Source: denoland/deno

Full disclosure: I'm a complete Deno newbie. This is probably not a Deno bug but a bug in my understanding of how to import modules.

I'm trying to import Lodash from https://deno.land/x/lodash_require/

import Lodash from "https://deno.land/x/lodash_require/mod.ts";

const words = ["Hello", "World"];

Lodash.forEach(words, (w: string) => {
  console.log(w);
});

When I run this:

deno hello.ts

I get the following error:

D:\deno>deno hello.ts
Compile file:///D:/deno/hello.ts
error: Uncaught Error: Protocol has to be file://
â–º module.ts:1199:11

1199     throw new Error("Protocol has to be file://");
               ^
    at fileURLToPath (module.ts:1199:11)
    at createRequire (module.ts:514:18)
    at mod.ts:4:18
bug

All 13 comments

cc @kevinkassimo

It seems createRequire(root) needs a file:/// root, that obviously won't work for remote modules.

Also, https://deno.land/x/lodash_require/mod.ts's dependency https://deno.land/x/lodash_require/lodash-npm doesn't exist? @TokenChingy

@nayeemrmn the reason is very simple: it is ported from Node and Node does not support remote URL loading.

I wonder if adding that support is a good idea or not, since it technically is outside of the scope of Node compatibility

@kevinkassimo Is the intention that it gets run in your local main module and not by remote libs? That would mean https://deno.land/x/lodash_require/mod.ts is authored wrong.

https://dev.jspm.io/lodash should work out-of-the-box:

â–¶ deno fetch https://dev.jspm.io/lodash
Download https://dev.jspm.io/lodash
Download https://dev.jspm.io/npm:[email protected]/lodash.dew.js

The bigger question is how to do we enable Node modules to be used as is done in this example. It's certainly valid to try to

import Lodash from "https://deno.land/x/lodash_require/mod.ts";

@ry the problem is with module itself; as read in README it wants you to clone a submodule - I think that's out of scope for require

@bartlomieju forgive me as I'm a Deno newbie. You mentioned that https://dev.jspm.io/lodash should work out of the box. I tried to import that but Deno complains. I guess my question is how do I import lodash using that URL?

@frankhale, right... It turns out I hit problem too:

Download https://unpkg.com/[email protected]/lodash.js
error: Uncaught ImportPrefixMissing: relative import path "util" not prefixed with / or ./ or ../ Imported from "https://unpkg.com/[email protected]/lodash.js"
â–º $deno$/dispatch_json.ts:40:11
    at DenoError ($deno$/errors.ts:20:5)
    at unwrapResponse ($deno$/dispatch_json.ts:40:11)
    at sendSync ($deno$/dispatch_json.ts:67:10)
    at resolveModules ($deno$/compiler_imports.ts:71:10)
    at processImports ($deno$/compiler_imports.ts:166:27)
    at processImports ($deno$/compiler_imports.ts:175:13)

Cloning the repo https://deno.land/x/lodash_require/ locally and following the installation instructions will work with a bit of manual editing to the mod.ts file.

I had to change

const lodash = require_("./lodash-npm");

to

const lodash = require_("./lodash");

and then fix my import statement like so:

import Lodash from "./lodash_require/mod.ts";

results:

D:\deno>deno --allow-read hello.ts
Compile file:///D:/deno/hello.ts
Hello
World

So this is sort of ugly and I'd rather have the module download in the same way as others (eg into the Deno cache location) but I can live with it for now.

I consider this a bug of createRequire. Not sure how to address it.

https://deno.land/x/lodash_require@5d8ab/mod.ts#L4

To implement this, I think there are at least some features we need to implement directly to Deno

Either

  • Ability to fetch synchronously or readSync/writeSync on connections, and API to retrieve Deno caching location (DENO_DIR or default)
    Or
  • Expose an API to request download and caching of URL, like deno fetch but exposed as a function call. Also this call has to have a synchronous version.

    • We cannot use dynamic import since we do not want to have downloaded code being executed. Also, this API also need to have an option to disable recursive downloading, thus meaning that the downloaded code won't be compiled as an ES module for recursive loading

    • To use the existing module infra, we need a reference to EsIsolate from State. This seems to be conflicting with recent changes, and I would imagine quite a bit pain over locking situation.

Well, if anyone finds this, in the meantime, this happens to work:

import 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js'
console.dir(_.difference([1,2,3],[3,4,5]))

@youurayy Thank you!!

I've been using the Lodash package from Pika lately and it's also working greatly.

import * as _ from 'https://cdn.pika.dev/lodash-es@^4.17.15';

let foo = ["Hello", "world", "Deno", "is", "awesome!"];

_.forEach(foo, (foo: string) => {
    console.log(foo);
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

watilde picture watilde  Â·  3Comments

justjavac picture justjavac  Â·  3Comments

ry picture ry  Â·  3Comments

benjamingr picture benjamingr  Â·  3Comments

zugende picture zugende  Â·  3Comments