-
Notifications
You must be signed in to change notification settings - Fork 916
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
Convert CommonJS projects to es6 modules #62
Comments
I'd love to know if this is possible. My understanding was that the plugin could understand common.js dependencies, but wouldn't support common.js entrypoints (the top-level webDependency package) because it couldn't get the export interface right without knowing what was being imported off of it. Do you know if that is true? |
Hi Fred. OK, to test this, I used a mapbox module, osmtogeojson, in a new temporary repo. The repo has an npm install of the current rollup and rollup-plugin-commonjs, along with the test module osmtogeojson:
I initially used this with an html file using a script tag, to convert an osm (open street map) format to geojson to make sure it all works. It did. So I then created an esm rollup via:
I ran this, changing the script version of the html file to a
It worked perfectly! Yay! I've used this before with good results. Is this what you were wondering about? Basically, many well formed modules using |
TLDR: I tried this on another es5 repo to make sure this is a reasonable approach, and it worked. Details: Another example: chart.js. I submitted an issue to them about modules, and in particular, showed how to create an es6 module via the rollup idea above. Just to make sure the above would still work, I created a new repo, with npm init, and installed rollup & plugins as well as chart.js.
I used this rollup.config.json:
I ran rollup via npx like this
Just to make sure it worked, I made a quick chart which worked.
|
So I think we're on to something here. I'd start with limiting this to explicit @pika/web.webDependencies rather than all of my package.json dependencies. I don't know how to test for success. We can test for rollup errors. And maybe build a simple html file that just imports the module and signaling a failure to load somehow. |
Over here crossing paths with you on chart.js. Already using chartjs in a project based on pikaweb (but the nasty old fashioned run around hacky way, per that chart.js issue). This would be amazing! |
Hi @krumware, glad you're joining the conversation. I can use a sanity check! Did you ever try the rollup which uses the rollup-plugin-commonjs? I'd love feed back. I did not look into the potential corner cases involving Moment for example. Moment has been converted to es6, but the issue is how would that work with the chart.esm.js mentioned above. I think the answer here is that chart.js has a rollup, dist/Chart.bundle.js, which includes Moment. So if we point pika/web to that, via @pika/web.webDependencies, then things should work. I'll give it a try. |
TIL! This could be really great, thanks for doing the research on this! Also because we use the commonjs plugin to handle internal, sub-dependencies, it looks like you can just point to common.js files (but not the package name) and @pika/web will already handle them, example:
I'm going to be on vacation for the next two weeks, and won't have regular access to internet. Which sucks timing wise, because this is really exciting. But It also sounds like there's not too much actual implementation work here, just thinking through the interface / how the user turns this on, is that correct? Open to any ideas here!
|
Yay! Glad it works out, especially basically as-is. And thanks for pointing at the two other issues which merge nicely with this. No worries about the timing, have a great, relaxing, insightful vacation. |
@backspaces Hi, I'm from issue #68, hope you don't mind my joining this conversation. (Likewise I'd be curious about your thoughts in that issue too.) So if I'm reading both of you correctly, the ability to bundle CJS modules such as "chart.js" and "osmtogeojson" is already available in @pika/web by just adding the main entry-point file (the same as its pkg.main) to pkg.[@pika/web].webDependencies? |
This seems to work! "webDependencies": [
"styled-components/dist/styled-components.browser.esm.js", import styled from '/web_modules/styled-components/dist/styled-components.browser.esm.js'; Although it's verbose. Normally I would suggest an optional alternative "alias" syntax, such as: "webDependencies": [
["styled-components", "styled-components/dist/styled-components.browser.esm.js"], Then we could just do this: import styled from '/web_modules/styled-components.js'; However, I think the plan in #68 would solve this in a cleaner and better way: let Pika automatically scan imports in user code, finding the "/web_modules/styled-components.js" path and determining from this that it must compile the "styled-components" NPM module. That said, Pika still wouldn't know exactly how to compile styled-components without first knowing tha it must find "dist/styled-components.browser.esm.js", which is not listed in styled-component's package.main: "main": "dist/styled-components.cjs.js",
"module": "dist/styled-components.esm.js", Those are both node-specific bundles, so styled-components may be an exception to this working smoothly. But in the general case, I think as long as Pika can find either "module" or "main" and correctly bundle it using rollup-plugin-commonjs as suggested by this issue, then this plan should work for a good majority of packages. |
Ah, this trick of putting Even though this is specific to styled-components, which was verified to be a strange exception, it's generally true about any package which doesn't have a proper I think as a reasonable workaround, users can let @pika/web know about potential "incorrect" packages like this, similar to the "alias" idea above. Maybe in conjunction with the plan in #68, instead of a whitelist, there would be an aliases entry: "@pika/web": {
"aliases": {
"styled-components": "styled-components/dist/styled-components.browser.esm.js", Here, devs would be able to specify "real" entry points for broken packages, and Pika would be able to "alias" them in a configuration with Rollup, by saying "every time you see styled-components, either directly, or via another package which is requiring it, use this file instead as the entry-point." |
I just verified that the concept itself works: import commonjs from 'rollup-plugin-commonjs'
import resolve from 'rollup-plugin-node-resolve'
export default {
input: [
'styled-components',
'styled-icons/fa-solid/Clipboard',
'Chart.js',
'react',
'react-dom',
],
output: {
dir: 'out',
format: 'esm',
},
plugins: [
renameHardcodedTest(),
resolve(),
commonjs(),
],
};
function renameHardcodedTest() {
return {
name: 'rename-hardcoded-test',
resolveId(src) {
if (src === 'styled-components') {
return 'node_modules/styled-components/dist/styled-components.browser.cjs.js';
}
return null;
},
};
} This works even with the import of styled-components found nested inside of styled-icons, and the output Clipboard.esm.js file contains The function I had to prefix the returned result with |
(It's worth noting that the example in that comment uses |
One problem with this Rollup config is that the structure of the output directory doesn't match what we're importing:
There's a few differences:
When I add
|
Regarding that last problem, Pika/web already seems to have the ability to do this, because it outputs modules matching the file/directory structure of webDependencies. But I can't for the life of me figure out where in the code this is happening. No output options seem relevant to it, none of the 5 plugins seem to make it happen. I'm just confused. |
Got that working! Turns out I needed to turn the array into a map: input: {
'styled-components': 'styled-components',
'styled-icons/fa-solid/Clipboard': 'styled-icons/fa-solid/Clipboard',
'Chart.js': 'Chart.js',
'react': 'react',
'react-dom': 'react-dom',
},
|
hey all! I'm back from vacation and really excited about this feature. I think there are two paths to go down that would make sense here:
What do people thing? I'm still catching up on issues/PRs, so apologies if I'm missing anything that's already been said outside of this thread. |
Update: the quick-fix (supporting CJS packages in the "webDependencies" whitelist) has been merged to master. It won't be released for a few more days. But, you can try it now via:
|
This immediately helped with socket.io-client, which is a classic case of a frustratingly almost-compatible browser module.
|
@krumware Are you still able to use socket.io-client with this set up? I can't seem to get it to work Edit: I got it to work. Instead of I'm also using chart.js so that import looks like: |
@bskimball sorry for the late reply. I haven't used it in some time, but your solution makes sense since importing the full file path is required. Also, Chart.js has a Next branch with esm support, unless they've already released 3.0+ |
TLDR: This is a feature request to manage common js dependencies as well as es6 module dependencies.
Details:
If my dependencies includes a common js project, try converting it to es6 modules via https://github.com/rollup/rollup-plugin-commonjs (which is already in pika/web's package.json devDependencies).
It would be fine to limit this to explicit @pika/web.webDependencies rather than all of my package.json dependencies.
The text was updated successfully, but these errors were encountered: