-
Notifications
You must be signed in to change notification settings - Fork 2
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
Changed extension bundling from Vite to webpack #311
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, only partial review before my day ended.
Reviewed 23 of 69 files at r1, all commit messages.
Reviewable status: 23 of 69 files reviewed, 1 unresolved discussion (waiting on @tjcouch-sil)
extensions/src/hello-someone/hello-someone.web-view.html
line 199 at r1 (raw file):
else setupWebView(); //# sourceURL=hello-someone.web-view.js
Shouldn't this be .html
now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is behind main by a few weeks, I think. It might be helpful to rebase/merge with main so that all the conflicts are sorted out sooner than later. For example, this PR updates @sillsdev/scripture
from 1.2.0 to 1.3.0, but main is already on 1.4.0. That might be the only conflict, but I wonder how many others there might be.
Reviewed all commit messages.
Reviewable status: 23 of 69 files reviewed, 1 unresolved discussion (waiting on @tjcouch-sil)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 18 of 69 files at r1.
Reviewable status: 23 of 69 files reviewed, 1 unresolved discussion (waiting on @tjcouch-sil)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow that looks like a lot of configuring, thanks for all your hard work on this. I'll publish this as is then look at your recent changes next.
Reviewed 46 of 69 files at r1.
Reviewable status: 62 of 70 files reviewed, 5 unresolved discussions (waiting on @lyonsil and @tjcouch-sil)
extensions/webpack/web-view-resolve-webpack-plugin.ts
line 113 at r1 (raw file):
} }
Thanks for all the coments in this file.
extensions/webpack/webpack.config.main.ts
line 44 at r1 (raw file):
globalObject: 'globalThis', library: { type: 'umd',
Err... why UMD library? AFAIK thats a really old format and not used much any more. As it is I'd generally advocate moving to ESM over CJS.
extensions/webpack/webpack.util.ts
line 192 at r1 (raw file):
library: { name: extension.dirName, type: 'umd',
Again output to UMD - I don't recommened this. AFAIK UMD supports switching between AMD and CJS but it doesn't (nor can it) support ESM. But I could be out of date.
src/extension-host/services/extension.service.ts
line 180 at r1 (raw file):
)) as AmbiguousExtensionModule; // Get the actual extension module based on what kind of module it is // __esModule is a property built into node. We're just using it here
Above I asked about the webpack output of UMD not being compatible with ESM. I guess this is how you are getting around that incomaptibility but I don't understand what is going on here.
Code quote:
__esModule
extensions/src/hello-world/hello-world.ts
line 65 at r1 (raw file):
* Simple web view provider that provides other React web views when papi requests them */ const reactWebView2Provider: IWebViewProvider & { webViewType: string } = {
This is not DRY - it's repeated 3 times. Either add webViewType: string
as an optional property of IWebViewProvider
or declare an inherited type in this file or back in src\shared\models\web-view-provider.model.ts
.
This makes me wonder if it should be a required property of IWebViewProvider
since it's needed to register the WebView provider. This is out of scope for this PR so this could be a separate issue.
Code quote:
IWebViewProvider & { webViewType: string }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pulled the branch and it is behaving well. There are a bunch of new MUI warnings in the browser console though. Also the fetching of JHN 11:35 from the USFM data provider hasn't worked yet on any of my runs (but it is fetching the other verses in the Hello World React tab so the provider is running). But startup and shutdown are much faster and cleaner so far - nice job.
Reviewed 7 of 7 files at r2, 1 of 1 files at r3, all commit messages.
Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @tjcouch-sil)
jest.config.ts
line 9 at r3 (raw file):
const { config: { compilerOptions }, } = typescript.parseConfigFileTextToJson('tsconfig.json', fs.readFileSync('tsconfig.json', 'utf8'));
That's a handy util to know about. Thanks. Was this needed because of the comments in tsconfig.json
?
Code quote:
typescript.parseConfigFileTextToJson
extensions/src/hello-world/web-views/hello-world.web-view.html
line 17 at r3 (raw file):
<div><button id="hello-someone" type="button">Hello Someone</button></div> <div id="hello-someone-output"></div> <div id="root"></div>
We end up with a second "Hello World" button inside this div. I guess that is testing raw React right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 20 of 69 files at r1, 1 of 7 files at r2, 1 of 1 files at r3, all commit messages.
Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @tjcouch-sil)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 6 unresolved discussions (waiting on @irahopkinson)
jest.config.ts
line 9 at r3 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
That's a handy util to know about. Thanks. Was this needed because of the comments in
tsconfig.json
?
Yep! This is TypeScript's special json parser that ignores comments, allows dangling commas, etc.
extensions/webpack/webpack.config.main.ts
line 44 at r1 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
Err... why UMD library? AFAIK thats a really old format and not used much any more. As it is I'd generally advocate moving to ESM over CJS.
AMD is very old. UMD is a special type that webpack allows that makes the module polymorphic to AMD, CJS, and global variable. It tries to import as it thinks the loader is expecting. I thought maybe this was causing the ambiguous module issues in extension.service.ts
, but it didn't fix when I changed it to 'commonjs'. But then you got me thinking, and I dug deeper and found 'commonjs-static'! I think this is pretty much what vite was doing before, and it is doing the same thing in dev and production (the module imports with activate
on it instead of inside default
). Thanks for pushing me to look harder.
I think I tried using ESM when I was first getting into loading extension code (before I understood webpack very well at all), and it didn't work for some reason. I bet it has something to do with how ERB configured the environment. It could be nice to update everything and not have to worry about CJS anymore. But right now I think everything pretty much needs to be CJS. I'll make an issue for investigating it.
Actually it seems the topic of ES vs CJS is rather split...
https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
https://gist.github.com/joepie91/bca2fda868c1e8b2c2caf76af7dfcad3 (warning: some language)
extensions/webpack/webpack.util.ts
line 192 at r1 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
Again output to UMD - I don't recommened this. AFAIK UMD supports switching between AMD and CJS but it doesn't (nor can it) support ESM. But I could be out of date.
Indeed UMD does support only AMD, CJS, and global variable. I changed this. See comment above.
src/extension-host/services/extension.service.ts
line 180 at r1 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
Above I asked about the webpack output of UMD not being compatible with ESM. I guess this is how you are getting around that incomaptibility but I don't understand what is going on here.
I didn't understand at first either; webpack was doing weird things on umd
. Now that I'm using commonjs-static
, it seems to be consistent! But I left the code for compatibility because why not
extensions/src/hello-someone/hello-someone.web-view.html
line 199 at r1 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
Shouldn't this be
.html
now?
I debated what to call it, honestly. But I thought maybe js would be clearer since it's just the script tag, not the whole html file, that Chrome displays. If you made two script tags, you would have to name them separately. I dunno; it's really hard to say. What's expected? I'll change to html for now. Let me know your thoughts.
extensions/src/hello-world/hello-world.ts
line 65 at r1 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
This is not DRY - it's repeated 3 times. Either add
webViewType: string
as an optional property ofIWebViewProvider
or declare an inherited type in this file or back insrc\shared\models\web-view-provider.model.ts
.This makes me wonder if it should be a required property of
IWebViewProvider
since it's needed to register the WebView provider. This is out of scope for this PR so this could be a separate issue.
I just decided to include the webViewType in the provider itself on a whim here. It's not required to do it this way as the webViewType is passed into the registration function.
I debated making it required on the webView and just inferring it when you register the provider, but I think that would disallow you from using one twice for two different types (which I guess could come in handy in some situation...? I dunno; seems nice to be flexible about it). I'll make another type that has it in this file. I don't know if it should go on the papi, though... Thoughts?
extensions/src/hello-world/web-views/hello-world.web-view.html
line 17 at r3 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
We end up with a second "Hello World" button inside this div. I guess that is testing raw React right?
Yep, there's an HTML and a React button in this web view that do the same thing.
…p testing the imports
…s to share click counter as an example event
…xtensions not working
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 8 of 8 files at r4, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @tjcouch-sil)
extensions/webpack/webpack.config.base.ts
line 16 at r4 (raw file):
* The module format of library we want webpack to use for externals and create for our extensions * * @see webpack.Configuration['externalsTye'] for info about external import format
nit: typo
Code quote:
externalsTye
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding not getting the USFM data provider: I think maybe the dotnet data provider is taking longer to load than the extension host + quick-verse + 5 seconds (our request timeout), so it's timing out. If you restart the extension host after starting, it doesn't happen again. It also doesn't happen in production. I think maybe webpack is just taking more system resources and making the dotnet provider too slow to start or something, but that's just a theory honestly. I haven't dug in too much. I increased the timeout to 10 seconds when not packaged, and I plan to file an issue regarding seeing if we can collapse some of these webpack processes into one with multiple configs in an array. I'm not sure yet why they aren't already set up this way to be honest. I could alternatively go ahead and mess around with that now if you'd prefer since increasing the timeout isn't really a very good option. Let me know your thoughts! Thanks! :)
Regarding the MUI warning: I have literally no idea why that doesn't show up in main. That's a problem with ref-selector.component.tsx
which hasn't been touched in 2 weeks. I made some fast adjustments, but I don't really even like what I did (put in a new unwieldy prop that seems very MUI-specific and not that helpful. Would be better to just refactor it well, but I didn't want to take the time to look into it right now). Will file an issue.
Reviewable status: complete! all files reviewed, all discussions resolved
extensions/webpack/webpack.config.base.ts
line 16 at r4 (raw file):
Previously, irahopkinson (Ira Hopkinson) wrote…
nit: typo
Done. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 13 of 13 files at r5, all commit messages.
Reviewable status: complete! all files reviewed, all discussions resolved
…estor Paranext must have them installed to be able to provide them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 22 of 69 files at r1, 2 of 7 files at r2, 7 of 8 files at r4, 13 of 13 files at r5, 2 of 2 files at r6, all commit messages.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @tjcouch-sil)
extensions/src/hello-world/web-views/hello-world-2.web-view.tsx
line 12 at r4 (raw file):
} = papi; globalThis.webViewComponent = function HelloWorld2() {
Is this a normal thing we're expecting webViews to do? It seems very fragile if there are multiple webViews trying to render at the same time.
extensions/webpack/webpack.config.base.ts
line 21 at r6 (raw file):
// commonjs-static formats the code to export everything on module.exports.<export_name> so it works // well in cjs or esm https://webpack.js.org/configuration/output/#type-commonjs-static export const LIBRARY_TYPE: NonNullable<webpack.Configuration['externalsType']> = 'commonjs-static';
When I was digging into another issue recently, I read in several places the ESMs work much better with tree shaking than CJS. I think you have a ticket to investigate moving to ESM, but I just wanted to comment that doing everything in CJS is may be bloating our packages.
extensions/webpack/webpack.config.base.ts
line 41 at r6 (raw file):
// Modules that Paranext supplies to extensions https://webpack.js.org/configuration/externals/ // All other dependencies must be bundled into the extension externals: [
Should the following components be in this list, too? That might be the cause of new MUI warnings.
@emotion/react
@emotion/styled
@mui/material
In a recent change of mine I added these to a peer dependencies list to resolve some MUI warnings.
c44a814
lib/papi-dts/papi.d.ts
line 57 at r6 (raw file):
var resourcesPath: string; /** * How much logging should be recorded. Defaults to 'info' if not packaged, 'error' if packaged
Very minor nit, but it looks like the source of this comment didn't use 1-line comments like the other variables preceding it.
src/shared/services/network.service.ts
line 181 at r5 (raw file):
// This approach is hacky but works well enough for now const expectedErrorMsg: string = `No handler was found to process the request of type ${requestType}`; const maxAttempts: number = globalThis.isPackaged ? 5 : 10;
Isn't this backwards? If it's packaged, isn't that when you said in your top-level PR comments that you wanted to increase the timeout period?
extensions/src/evil/evil.js
line 15 at r4 (raw file):
// This will be blocked and will suggest the papi.storage api. const fs = require('fs'); logger.error(`Evil: Successfully imported fs! fs.readFileSync = ${fs.readFileSync}`);
When I'm looking at the console I find myself wondering sometimes if the "Evil" output is telling me something good or something bad. If you're tweaking these anyway it might be nice to put "GOOD" or "BAD" near the start of each message to make it clear. Sometimes I'm not looking at a console with color, and that's the only obvious difference between "info" and "error" I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @lyonsil)
extensions/src/hello-world/web-views/hello-world-2.web-view.tsx
line 12 at r4 (raw file):
Previously, lyonsil (Matt Lyons) wrote…
Is this a normal thing we're expecting webViews to do? It seems very fragile if there are multiple webViews trying to render at the same time.
Yes, this is how we have been getting the component for a while now. Each iframe has its own global context. Though it may get tricky if we want to share webviews without wrapping them in a new iframe. Maybe we ought to consider how we can improve this. The challenge is that this code is executed directly in a script on the frontend, not imported anywhere as a module. I made issue #323 to investigate revising this (will fill it in later)
extensions/webpack/webpack.config.base.ts
line 21 at r6 (raw file):
Previously, lyonsil (Matt Lyons) wrote…
When I was digging into another issue recently, I read in several places the ESMs work much better with tree shaking than CJS. I think you have a ticket to investigate moving to ESM, but I just wanted to comment that doing everything in CJS is may be bloating our packages.
Thanks for the info! #321
extensions/webpack/webpack.config.base.ts
line 41 at r6 (raw file):
Previously, lyonsil (Matt Lyons) wrote…
Should the following components be in this list, too? That might be the cause of new MUI warnings.
@emotion/react @emotion/styled @mui/material
In a recent change of mine I added these to a peer dependencies list to resolve some MUI warnings.
c44a814
Unfortunately importing component libraries is not simple as component libraries usually have code that ties styles from each component into the document when the component is imported. If you import a component in the renderer main frame then pass it down to extensions' iframes, they will not have styles. We saw this issue with built-in papi react components for a while, which is one reason we made them their own independent library. I'm not sure about emotion stuff (it might pass down just fine! Probably worth some investigation), but it seems we need to bundle mui/material into papi-components for the reasons I just mentioned. I don't know that any of our extensions have tried using emotion yet (I do not use it personally). If you would like to file an issue to investigate providing these libraries instead of bundling them into extensions, you're welcome to do so.
lib/papi-dts/papi.d.ts
line 57 at r6 (raw file):
Previously, lyonsil (Matt Lyons) wrote…
Very minor nit, but it looks like the source of this comment didn't use 1-line comments like the other variables preceding it.
Unfortunately a one-liner would be literally 101 characters :( so it's multi-line
src/shared/services/network.service.ts
line 181 at r5 (raw file):
Previously, lyonsil (Matt Lyons) wrote…
Isn't this backwards? If it's packaged, isn't that when you said in your top-level PR comments that you wanted to increase the timeout period?
In development, everything takes so long to start up and such that I seemingly needed to increase the timeout. I figured it's best to leave everything quick in production. Hopefully we won't need this to be dependent on packaging after #313
extensions/src/evil/evil.js
line 15 at r4 (raw file):
Previously, lyonsil (Matt Lyons) wrote…
When I'm looking at the console I find myself wondering sometimes if the "Evil" output is telling me something good or something bad. If you're tweaking these anyway it might be nice to put "GOOD" or "BAD" near the start of each message to make it clear. Sometimes I'm not looking at a console with color, and that's the only obvious difference between "info" and "error" I think.
Done. Good call!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r7, all commit messages.
Reviewable status: complete! all files reviewed, all discussions resolved
extensions/webpack/webpack.config.base.ts
line 41 at r6 (raw file):
Previously, tjcouch-sil (TJ Couch) wrote…
Unfortunately importing component libraries is not simple as component libraries usually have code that ties styles from each component into the document when the component is imported. If you import a component in the renderer main frame then pass it down to extensions' iframes, they will not have styles. We saw this issue with built-in papi react components for a while, which is one reason we made them their own independent library. I'm not sure about emotion stuff (it might pass down just fine! Probably worth some investigation), but it seems we need to bundle mui/material into papi-components for the reasons I just mentioned. I don't know that any of our extensions have tried using emotion yet (I do not use it personally). If you would like to file an issue to investigate providing these libraries instead of bundling them into extensions, you're welcome to do so.
Ok - I'm not primarily concerned with providing vs bundling per se. I am just thinking about eliminating warnings and errors coming from our dependencies. I haven't been running this new branch yet, but if there are new MUI warnings then we will need a ticket to eliminate them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: complete! all files reviewed, all discussions resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: complete! all files reviewed, all discussions resolved
extensions/webpack/webpack.config.base.ts
line 41 at r6 (raw file):
Previously, lyonsil (Matt Lyons) wrote…
Ok - I'm not primarily concerned with providing vs bundling per se. I am just thinking about eliminating warnings and errors coming from our dependencies. I haven't been running this new branch yet, but if there are new MUI warnings then we will need a ticket to eliminate them.
I don't believe there are new MUI warnings. Jolie just reported the MUI issue Ira was seeing on my branch on a totally separate branch. I don't know why I didn't see that error when I tried main for a bit yesterday. I made a quick fix here anyway, but a better fix should be made long-term: #322
?inline
at the end of the import.tsx
in your webview imports if you want (optional).ejs
extension to.html
since that feels more natural and we can do that nowreact/jsx-runtime
for newer React syntaxevil
extension because webpack was being greedy and absorbing the imports, ignoring thrown errors, and giving{}
empty object for unresolved imports. Not that this breaks anything; just not as good testingtemp-vite
totemp-build
lib
->src
, build filesdist
, distributable zip filesrelease
release
directory@sillsdev/scripture
an external dependency since many extensions will likely share ithelloWorld.onHelloWorld
network event to demonstrate using them. All the hello world webviews sync up their click count (though this would probably be easier with a data provider)--logLevel
command-line-argumentResolves #232
This change is