-
-
Notifications
You must be signed in to change notification settings - Fork 148
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
Introduce npm+webpack to build the app #554
Comments
I strongly support this |
This guide seems useful (much appreciated in the comments): |
This is very interesting. Moderne JS development requires at least these two technologies. What do you think? |
@Bam92 Yes. Personally I think the time has come for this, not least because it would enable use of frameworks that now expect this structure, automatic updating of dependencies, and possibility of using supersets of JS such as TypeScript, compiling for all targeted browsers with Babel (which makes use of antiquated dependencies like jQuery unnecessary). We believe it is a huge amount of work, however... |
@Jaifroid Yes, it is a huge amount of work. But I'd suggest migrating little by little. |
This might be some work for an upcoming hackathon |
Which hackathon do you mean here? |
I mean it's something I could work on in the following months |
Another good howto with webpack: https://github.com/petehunt/webpack-howto . |
This tool could be useful in transforming codebase from ES5 to ES6 (including modules / import / export): https://github.com/lebab/lebab It is "the opposite of babel", hence its spelling ("lebab"). These codemods could also be useful: https://github.com/5to6/5to6-codemod |
Which browsers are you looking to support? ES6 support is quite widely available nowadays. For example, from https://caniuse.com/es6-class and https://caniuse.com/arrow-functions
I'm still very new to how Kiwix works, but as I understand it is used as browser extension or local server, not as website. Which means there's a certain amount of freedom in users deciding to upgrade. Which, if the data format remains compatible, should provide a good experience for users on the previous version for a long time. It could even remain offered as a download of that older version. Looking at the README, however, it seems like maybe this won't be needed since all versions that have "store" entries or other downloads support ES6. And for IE11, it requires a manual installation, which users could do by checking out the relevant Git tag of the last version before this lands. It might be worth considering as such, to follow the native web platform and adopt features as they come available. We can ship polyfills and shims for significant new APIs that older browsers don't yet have (e.g. Object.assign), but we could let the programmatic syntax be that of the newest we can safely use in all supported browsers - which could be ES6 today if we drop IE11 support for new releases. |
@Krinkle Thanks for your thoughts. Much appreciated. I think the attraction of npm-webpack-bable for us is twofold:
Yes, it adds a compile step, but usually this is a one-liner, and can be integrated into VS Code or similar for testing and development. In terms of what we're supporting, currently we're keeping IE11, Windows Mobile (W10M) and an old Firefox OS on life support, but the main targets are indeed ES6-compatible. But there are bigger structural issues in the code that represent potential watersheds of deprecation for older browsers that core-js/babel would not help with:
So we're under no illusions that npm-webpack-babel would solve everything, but it does seem like a good way to modernize the codebase and allow us to use new features of JS more freely, and above all to manage dependencies. |
What @Krinkle suggests here is to drop compatibility with the oldest browsers that don't support ES6. They could still run an old version of kiwix-js (that we could still provide). It would allow to code with ES6, and run this code directly, without transpiling. Kiwix-js is currently very conservative on browser support. If there is a reasonable way to keep support for old browsers, we try to do it. So if transpiling is not a big problem, we'll probably keep it. |
OK, so I think the conclusion is: we want npm-webpack, but are not yet prepared to drop IE11 and other old browsers/webviews that are not compatible with ES6. Therefore, the npm-webpack configuration should ideally include core-js/babel and transpilation, or that can be a separate issue. |
* Load qunit package from npm. Start of a larger transition, ref kiwix#554. * Update QUnit from 2.3 to 2.12. * Use Karma for the running of unit tests (instead of Nightwatch). While it was possible to use a fake "UI" test to run a QUnit web page with Nightwatch, this was not ideal. This had numerous limitations, such as: - relies on fragile an unsupported web scraping to collect results, which can easily break between versions. ref kiwix#660. - results provide limited debugging information when a test fails. - cannot easily be run locally from the command-line since the Nightwatch config is currently written for SauceLabs, and creating a local configuration is not easy because Nightwatch has a hard requirement on webdriver (which makes sense for UI tests), which people usually do not have installed or may be incompatible with the current version of their browser. These then also have to be configured and started etc. - cannot easily be run in a secure container separate from your personal computer, thus putting personal data at risk. - lacks wider integration and plugins to enrich unit testing, such as test coverage reports. * Using Karma means: - You can run 'npm test' locally during development and have it automatically run the tests in headless Firefox and Chrome and report back, all from the command-line. - The same exact runner is also used in CI with SauceLabs for additional browser coverage (same as before). - It has no external dependencies other than the plain web browser itself. This means if you have a development container (e.g. based on Docker) that has Node.js + Firefox + Chromium, you can run the tests from within there without exposing anything from your personal computer, except the current working directory. <https://timotijhof.net/posts/2019/protect-yourself-from-npm/> - In a future change, we can plug in karma-coverage to generate a test coverage report, and then submit this to Codecov or Coveralls, ref kiwix#528. * I have restructured the Travis CI file so that the cross-browser test in SauceLabs are skipped for PRs from forks. Instead, those PRs will run the unit tests in local Fireox and Chrome within Travis CI. This avoids the confusing failures and still gives (some) useful results. The tests that Travis CI runs are the same as what users can run locally if they invoke `npm test` (after a one-time run of `npm install` to fetch dependencies into the local node_modules directory). This restructuring uses the 'stages' feature which is not compatible with the 'deploy' feature. I had converted the two deploy stages to use the 'stages' feature as well so that these continue to work. * I have pinned the version of 'http-server' and 'nightwatch' in package.json so that these don't silently switch major versions that may contain breaking changes. Fixes kiwix#653.
Just stumbled across a more modern (and lightning fast) module / build solution appropriately called Vite: It has IE11 support via an official plugin (that harnesses babel, I believe). It also supports TypeScript or vanilla JS. Comes bundled with a node-based dev server and production of course. Interesting video about it here: https://www.youtube.com/watch?v=LQQ3CR2JTX8 |
A document on how to convert a JavaScript project to TypeScript, and use TypeScript modules instead of RequireJS/AMD modules: https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html It might be possible not to have a bundler other than TypeScript itself, which can also transpile code down to ES5 natively. Obviously you then have to compile code in order to run it in a browser, but it's just an npm command. |
@mossroy We have various possible strategies outlined above, and I'm happy to keep adding useful info to this thread as I find things, but I wonder if we're in a position to choose a path forwards. I quite like the idea of a combination of TypeScript for type checking, and babel for fine-grained control over transpiling, though on its own TrypeScript engines can do most transpiling to ES5, maybe enough for our needs. I don't have any experience, though. To be clear, you can essentially keep writing JavaScript in a TypeScript project. FWIW, MWoffliner uses TypeScript, as you can see from https://github.com/openzim/mwoffliner/tree/master/src . That could have some advantages for us in terms of shared knowledge of tooling. |
I don't have much experience on this either, so don't have a strong opinion. Regarding the language (javascript vs typescript), I don't have a strong opinion either. To me, the main goal is to be able to use recent ECMAscript features with some native transpiling/polyfilling |
OK, maybe we can experiment a bit with Vite in a branch. There's a guide on converting an existing project here: https://css-tricks.com/adding-vite-to-your-existing-web-app/ The guide is for people using webpack, but the concepts should be similar. It seems as if stripping out ReguireJS and changing our define statements to import statements using ES6 module syntax, and similar for export statements, would be the first step. If it runs with native modules in a modern browser, then adding vite as a fast transpiler ought to be relatively easy (famous last words). |
This month is quite busy for me, but I follow you |
I also probably can't do anything on this till end of month, but it's good to have a notional path to experiment with even if only mentally. |
It looks like Vite has also developed a very fast testing framework called, wait for it..., https://vitest.dev/ |
Some more useful Vite examples here: https://dev.to/stormkit/migrating-stormkit-from-webpack-to-vite-5429. |
Another guide: https://dev.to/tythos/porting-from-requirejs-to-es6-ip |
OK, having made a big effort to remove RequireJS from the Kiwix JS Windows/Linux version in kiwix/kiwix-js-pwa#393 and use modern module imports instead, I've had a very frustrating time trying to find a compatible way of packaging the modules. Everything works fine in a browser that supports ES6 modules natively. I tried So, I backtracked and tried Then I tried to integrate Finally, I tried supposedly trusted workhorse So I'm now a bit stumped. I could try TypeScript, but if the others can't work out how to transpile ES6 modules, there doesn't seem much hope that TS will be able to do it, as it's not intended to be a bundling solution. |
I tried esbuild, which looked very positive, and makes a bundle that nearly runs. However, it doesn't have support for dynamic imports, so there is no fallback from wasm to asm, and more importantly, if using a static import (of just one or the other), then it warns that it can't use |
I've finally managed -- after a lot of fiddling and working around problems with core-js polyfills in IE11 -- to bundle a usable app for both modern and legacy browsers using https://rollupjs.org/ and its Babel plugin. 😊 Usable code is in kiwix/kiwix-js-pwa#393, with the app being built to the Since Rollup is used as the bundler behind https://vitejs.dev/, there is hope for adding the Vite goodies as well, though for now I'm focusing on getting a fully working app bundle, and the dev front end can be added later. When it's implemented, working, and fully tested in KJSWL, I'll backport here. 🍀 |
The PR for this issue is #1025. More discussion there. |
It would have some advantages. At least :
I thought about implementing this several times, but the following drawbacks kept me from doing it, so far :
The text was updated successfully, but these errors were encountered: