peerigon/parse-domain

Bad export directive since 42f54e8010c077c5375f0c96ab35a12bad35d3f4 (Jan 23)

meunierfrederic opened this issue · 4 comments

Hello,

Thanks for your very useful code.

in src/main.ts
from './parse-domain'
becomes
from './parse-domain.js'
which throws an error when we are using your module.

Same for
from './sanitize.js'

Thanks,

Frédéric

jhnns commented

Not sure what you mean :) The import is working fine: https://stackblitz.com/edit/node-3ejlnp?file=package.json,index.js

Maybe you need to switch to ECMAScript modules to make it work. See #146 (comment)

Thanks @jhnns, #146 comment was useful.
I'm not really confident with my understanding about subtle differences between typescript and ECMA Script. Our need is to use parse-domain in a typescript/commonJs project. Here an example of code that run successfully. Do you know if there are some better ways to use parse-domain in typescript/commonJs project?

src/index.ts:

import type { parseDomain, fromUrl, ParseResultType } from "parse-domain";
import("parse-domain").then((parseDomainApi) => {
  main(parseDomainApi);
});

async function main(parseDomainApi: { parseDomain: typeof parseDomain; ParseResultType: typeof ParseResultType; fromUrl: typeof fromUrl }) {
  const parseResult = parseDomainApi.parseDomain(parseDomainApi.fromUrl("https://www.münchen.de?query"));

  if (parseResult.type === "LISTED") {
    console.log("subDomains:", parseResult.subDomains);
    console.log("domain:", parseResult.domain); // "xn--mnchen-3ya"
    console.log("topLevelDomains:", parseResult.topLevelDomains); // ["de"]
  }
}

jhnns commented

Yes, that's basically it, though I'd rewrite that example to

const parseDomainModule = import('parse-domain');

async function parseDomain(url) {
  const { parseDomain, fromUrl } = await parseDomainModule;

  return parseDomain(fromUrl(url));
}

parseDomain('https://www.münchen.de?query').then((result) => {
  console.log(result);
});

https://stackblitz.com/edit/node-q4wvvq?file=package.json,index.js

jhnns commented

Alternatively, you could write a helper function that initializes all ESM dependencies before starting the application:

// the helper
const modules = {
  ['parse-domain']: import('parse-domain'),
};

const initializedModules = Object.create(null);

exports.require = (moduleName) => {
  if (moduleName in initializedModules === false) {
    throw new Error(`Unknown module ${moduleName}`);
  }
  return initializedModules[moduleName];
};

exports.isReady = (async () => {
  for (const [moduleName, modulePromise] of Object.entries(modules)) {
    initializedModules[moduleName] = await modulePromise;
  }
})();
// on application start
const esm = require('./esm.js');

esm.isReady.then(() => {
  require('./app.js');
});
// in your app
const esm = require('./esm.js');
const { parseDomain, fromUrl } = esm.require('parse-domain');

console.log(parseDomain(fromUrl('www.münchen.de')));

https://stackblitz.com/edit/node-whxrib?file=esm.js,start.js,app.js