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

Error in ESM library #229

Closed
Dav2070 opened this issue Dec 21, 2022 · 11 comments
Closed

Error in ESM library #229

Dav2070 opened this issue Dec 21, 2022 · 11 comments
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@Dav2070
Copy link

Dav2070 commented Dec 21, 2022

I want to use Pitsby in my JS library, but pitsby build always throws the following error:

No pitsby.config.js has been found.

Digging deeper, as the file obviously exists, it turns out that Pitsby can't load it, as my library is an ES module, with package.json containing "type": "module". This error is thrown here:

Error [ERR_REQUIRE_ESM]: require() of ES Module /home/dav/Projekte/web/dav-ui-components/pitsby.config.js from /home/dav/Projekte/web/dav-ui-components/node_modules/@glorious/pitsby/src/cli/services/file.js not supported.
Instead change the require of pitsby.config.js in /home/dav/Projekte/web/dav-ui-components/node_modules/@glorious/pitsby/src/cli/services/file.js to a dynamic import() which is available in all CommonJS modules.

Looking at #223, support for ES modules seems to be already implemented. But I don't understand how to use Pitsby in an ES module correctly. So any help with getting Pitsby to run would be much appreciated. You can find my library here, feel free to try it out if needed.

@rafaelcamargo
Copy link
Member

Hey @Dav2070, how are you?

It's worth noticing that ES6 support is intended to third-party code (in your case, the modules related to you UI lib), not to the Pitsby's config file. The configuration file should be written using CommonJS syntax as follows:

module.exports = {
  // Your configuration. This file should be saved at the root of your project (aside package.json).
}

Could you please paste your pitsby.config.js file here? So I can figure out better what probably is going wrong.

@rafaelcamargo rafaelcamargo added the help wanted Extra attention is needed label Dec 21, 2022
@Dav2070
Copy link
Author

Dav2070 commented Dec 21, 2022

Hi @rafaelcamargo, thanks for the quick response! I am fine, I hope you are too :)

I'm using the most basic config file here:

module.exports = {
  projects: [
    {
      engine: 'vanilla',
      collectDocsFrom: './src'
    }
  ],
  styles: [],
  scripts: [
    './dist/index.js'
  ],
  other: []
}

My index.js looks like this, simplified:

import { Button, buttonTagName } from './src/button/button.js';
import { Checkbox, checkboxTagName } from './src/checkbox/checkbox.js';
import { ContextMenu, contextMenuTagName } from './src/context-menu/context-menu.js';

export { Button, Checkbox, ContextMenu };

Is there a way to use it like this or do I have to compile my code to CommonJS?

@rafaelcamargo
Copy link
Member

rafaelcamargo commented Dec 21, 2022

Hey, @Dav2070!

Investigating the issue, I just learned that since your package.json defines type as module, Pitsby's configuration file must be named as pitsby.config.cjs to let NodeJS know that the configuration file is written using CommonJS, not ES6.

In addition, I just released a couple other fixes for bugs I discovered along this investigation. So please install the latest version (1.32.2) and see if works fine for you now 😉

UPDATE

Important to notice that your Pitsby's config file should be written as follows:

// pitsby.config.cjs

module.exports = {
  projects: [
    {
      engine: 'vanilla',
      collectDocsFrom: './src'
    }
  ],
  scripts: [
    { src: './dist/index.js', type: 'module' }
    // This is the way we tell Pitsby to add type as module to the script tag
    // inserted into the index.html of the documentation
  ],
  other: [
    './dist/src/'
  ]
  // You need to declare all the files that "./dist/index.js" imports itself,
  // otherwise they won't be found by the generated documentation.
}

@Dav2070
Copy link
Author

Dav2070 commented Dec 21, 2022

It now works flawlessly, thank you!

@Dav2070 Dav2070 closed this as completed Dec 21, 2022
@Dav2070
Copy link
Author

Dav2070 commented Dec 21, 2022

I have one more question: Should I use the .cjs extension for the doc files too? With button.doc.js I get the same error as with the config file:

image

And renaming the file to button.doc.cjs Pitsby seems to ignore the file, as I can't see any component in the web app.

@rafaelcamargo
Copy link
Member

rafaelcamargo commented Dec 22, 2022

Hey, @Dav2070!

My fault 🤦‍♂️ . I made the necessary adjustments to support configuration files as .cjs and forgot the necessary changes to support also the documentation files.

Just released another version (v1.32.3) with this improvement. Please, let me know if this new version works for you.

UPDATE

v1.32.4

@Dav2070
Copy link
Author

Dav2070 commented Dec 23, 2022

Thank you for the update! The doc files now work as well.

I don't want to use even more of your time, but now I get the following error in the browser console:

image

This is caused in the generated button.js, which contains the following line:

import { LitElement, html } from 'lit';

If I use an url to import the package, it works. So this probably means the node_modules are not available in this context.

import { LitElement, html } from 'https://unpkg.com/lit@2.2.4';

I'm not sure if this is a problem in my library and if I should compile my code in a different way. I will continue to search for a better solution and let you know if I find one.

Thanks again for the help so far, I really appreciate that!

@rafaelcamargo
Copy link
Member

rafaelcamargo commented Dec 24, 2022

Hey, @Dav2070!

It seems to be something related to the import itself. In the Browser context, all import paths must be relative to the page on which it appears. In this case, I think it's necessary to:

  • Definelit as an asset on Pitsby's config file
  • Use the importmap Browser resource to map Lit's absolute path ('lit') to its respective relative path.

More or less like this:

// pitsby.config.cjs

module.exports = {
  projects: [
    {
      engine: 'vanilla',
      collectDocsFrom: './src'
    }
  ],
  scripts: [
    { src: './src/doc.importmap.js', type: 'importmap' },
    { src: './src/doc.index.js', type: 'module' }
  ],
  other: [
    './dist/src/',
    './node_modules/lit/index.js'
  ]
}
// src/doc.importmaps.js

{
  'imports': {
    'davComponents': '/external/dist/src/index.js',
    'lit': '/external/node_modules/lit/index.js'
  }
}
// src/doc.index.js

import * as davComponents from 'davComponents';

window.davComponents = davComponents;

If everything works, all your components will be available through the global variable davComponents e you will be able to access them inside any controller declared in documentation files.

For the next two weeks I'll be vacationing, but when I come back, I'll fork your repo and make some experiments. I never used Pitsby this way (importing ES6 files) and also never built components using Lit, so I am a bit curious to see if they work well with Pitsby ✌️

@Dav2070
Copy link
Author

Dav2070 commented Jan 8, 2023

Hey @rafaelcamargo, thanks for the suggestion! I tried this some time ago, but Pitsby doesn't like the importmap file, as it contains only the json and no export or actual JS code. But I will need to try this again to tell you more.

Anyway, I will wait for your results with my component lib. If there is something where I can help you, let me know!

@rafaelcamargo
Copy link
Member

rafaelcamargo commented Jan 12, 2023

Hey, @Dav2070! Just found and resolved the remaining issues.

  1. The first one is with importmap. Browsers still don't support importmap coming from external sources (just in-line), so I needed to improve Pitsby to allow users to indicate whether a script declared in the configuration file should be in-line. I released this feature on Pitsby's latest version (1.33.0).

  2. Since browsers don't have access to your file system, just to the files present inside the Pitsby directory, you must manually declare every file requested by all your files so Pitsby can copy them to its directory. It's like having to resolve the dependency tree of your component library manually, a work similar of what Webpack does when it's generating a bundle (it's a little hard work, I confess, but that's still the price to import every ES6 module independently).

As you could see, I forked your repo and added to it the necessary commits to make Pitsby documentation work with your components. I also configured the deploy of the documentation using Firebase ($0 costs) to offer you an example on how to do that. You can visit it at https://dav-ui-components.web.app/

At last, all this challenges gave me an ideia. I will try (in the coming months) to create a dedicated Pitsby project only to explore Web Components and link this project on the current Pitsby's website to serve as an example on how to configure Pitsby to document Web Components using native ES6 modules ✨

If you need something else, please let me know. Have a nice time documenting your components 🙌

@rafaelcamargo rafaelcamargo self-assigned this Jan 12, 2023
@rafaelcamargo rafaelcamargo added the enhancement New feature or request label Jan 12, 2023
@Dav2070
Copy link
Author

Dav2070 commented Jan 12, 2023

Thank you, this is perfect! I just implemented your changes and deployed to DigitalOcean, the docs are now available at components.dav-apps.tech 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants