mathjs icon indicating copy to clipboard operation
mathjs copied to clipboard

How to use custom bundle

Open losfree opened this issue 3 years ago • 9 comments

I'd like to make a simple calculator based on mathjs ,only + - * / and evaluate, but it seems I dont get correct usage of custom bundle. when following the example custom_loading.js, I got the error message bellow

`root@iZu:/usr/local/lib/node_modules/mathjs/examples/advanced# npx webpack custom_loading.js -o custom_loading.bundle.js --mode=production assets by status 0 bytes [cached] 1 asset

ERROR in main Module not found: Error: Can't resolve 'custom_loading.js' in '/usr/local/lib/node_modules/mathjs/examples/advanced' Did you mean './custom_loading.js'? Requests that should resolve in the current directory need to start with './'. Requests that start with a name are treated as module requests and resolve within module directories (node_modules). If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too. resolve 'custom_loading.js' in '/usr/local/lib/node_modules/mathjs/examples/advanced' Parsed request is a module using description file: /usr/local/lib/node_modules/mathjs/examples/package.json (relative path: ./advanced) Field 'browser' doesn't contain a valid alias configuration resolve as module /usr/local/lib/node_modules/mathjs/examples/advanced/node_modules doesn't exist or is not a directory /usr/local/lib/node_modules/mathjs/examples/node_modules doesn't exist or is not a directory looking for modules in /usr/local/lib/node_modules/mathjs/node_modules single file module using description file: /usr/local/lib/node_modules/mathjs/package.json (relative path: ./node_modules/custom_loading.js) no extension Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/mathjs/node_modules/custom_loading.js doesn't exist .js Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/mathjs/node_modules/custom_loading.js.js doesn't exist .json Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/mathjs/node_modules/custom_loading.js.json doesn't exist .wasm Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/mathjs/node_modules/custom_loading.js.wasm doesn't exist /usr/local/lib/node_modules/mathjs/node_modules/custom_loading.js doesn't exist /usr/local/lib/node_modules/node_modules doesn't exist or is not a directory looking for modules in /usr/local/lib/node_modules single file module No description file found in /usr/local/lib/node_modules or above no extension Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/custom_loading.js doesn't exist .js Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/custom_loading.js.js doesn't exist .json Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/custom_loading.js.json doesn't exist .wasm Field 'browser' doesn't contain a valid alias configuration /usr/local/lib/node_modules/custom_loading.js.wasm doesn't exist /usr/local/lib/node_modules/custom_loading.js doesn't exist /usr/local/node_modules doesn't exist or is not a directory /usr/node_modules doesn't exist or is not a directory /node_modules doesn't exist or is not a directory

webpack 5.28.0 compiled with 1 error in 153 ms`

ubuntu 20.04

As I'm new to js and mathjs, hoping for any advice, thanks

losfree avatar Mar 24 '21 14:03 losfree

When I try out the npx webpack it complains about needing to install a webpack CLI, I guess there where breaking changes in that regard. Would be great to update the example with more explanation or changed

I'd like to make a simple calculator based on mathjs ,only + - * / and evaluate

the evaluator of mathjs may be a bit heavyweight in that case, there are more lightweight alternatives out there, but it's up to you of course :)

josdejong avatar Mar 27 '21 12:03 josdejong

@losfree

The answer is on the second line of the error message you received:

Did you mean './custom_loading.js'?

So, instead of:

import x from 'custom_loading.js'

Do:

import x from './custom_loading.js'

redbar0n avatar Mar 10 '22 12:03 redbar0n

I think there's more going on here. One gets a tiny bit farther by trying:

npx webpack ./custom_loading.js -o custom_loading.bundle.js --mode=production

But then the error becomes

Module parse failed: 'import' and 'export' may appear only with 'sourceType: module' (1:0)

So then one can try renaming the file to custom_loading.mjs and trying: npx webpack ./custom_loading.js -o custom_loading.bundle.js --mode=production But that just leads to the error:

Module not found: Error: Can't resolve '../..' in '/home/glen/code/mathjs/examples/advanced'
Did you mean 'index.js'?
BREAKING CHANGE: The request '../..' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

And here the "did you mean" line does not help, as there is no index.js I also tried it from the root directory, with the path examples/advanced/custom_loading.mjs, and that produced still other errors. If anyone can provide exact directions on how to make the bundle for the custom_loading.js please either file a PR putting that method in the comments of custom_loading.js, or provide the instructions here, thanks!

gwhitney avatar Mar 22 '22 01:03 gwhitney

Thanks for looking into this. We should get this example running again.

Some ideas:

  • It is maybe fixed by changing the import {...} from '...' into const {...} = require(...) (using old fashioned CommonJS)
  • When renaming the example to *.mjs, all imports need "real" paths, so indeed you will probably need to rename import {...} from '../..' to import {...} from '../../lib/cjs/index.js' (the file where the main file in package.json is pointing to).

josdejong avatar Mar 28 '22 09:03 josdejong

OK, well, both of the options in the last comment at least allow webpack to produce something. That is to say, if I make the change from the first bullet and execute npx webpack ./custom_loading.js -o custom_loading.bundle.js --mode=pr oduction I actually get a bundle (not exactly sure how to test it). And similarly, if I instead change the path for the import as in the second bullet and rename the flle to custom_loading.mjs and execute npx webpack ./custom_loading.mjs -o custom_loading.bundle.js --mode=production I again get a bundle. But clearly all is not well even so, because the bundle in the first case is 662 K and the bundle in the second case is 953 K, and I was expecting the bundle to be pretty small because it doesn't call for very much... but I really know next to nothing about webpack, so I am not equipped to delve into this further.

gwhitney avatar Mar 30 '22 04:03 gwhitney

Good to know that that at least produces a working bundle.

It could very well be that I used import on purpose because tree shaking worked only (or mostly) with ES modules at that time.

Looking at the size of the full, minified bundle at https://unpkg.com/browse/[email protected]/lib/browser/ shows 682 kB. If the bundle you get are 662 KB and 953 KB, the tree shaking is clearly not working at all 🤔 . I guess there is additional configuration needed nowadays.

I do know that the tree shaking can work, because we have a unit test validating that, see https://github.com/josdejong/mathjs/tree/develop/test/node-tests/treeShaking.

Anyone able to debug this further? Help would be welcome.

josdejong avatar Mar 30 '22 09:03 josdejong

As for what to expect with bundle reductions, see: https://mathjs.org/docs/custom_bundling.html#bundle-size

josdejong avatar Mar 30 '22 09:03 josdejong

I think tree-shaking is working for me? The non-gzipped size of my webpack chunk containing math functions, which includes a fairly large custom webpack bundle, is 340.21 KiB. When I introduced the custom bundling a few months ago, it dropped our overall bundle size by about 300 kilobytes.

Since I'm using Typescript, I take care that if I import directly from 'mathjs' it is only import type imports which will get erased---the main exceptions being the import of the bundler functions themselves, and in tests which aren't bundled.

In JS you would just be sure to not import directly from 'mathjs' outside the custom bundler module. Import from the custom bundle instead. (I guess this is stating the obvious---just for contrast with TS.)

My Vue / Webpack configuration in case it's helpful to anybody:

const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
	productionSourceMap: false,
	configureWebpack: {
		resolve: {
			plugins: [new TsconfigPathsPlugin({/* options: see below */})]
		},
		optimization: {
			minimize: true,
			sideEffects: true,
			usedExports: true,
		}
	},
};

joshhansen avatar Jul 14 '22 20:07 joshhansen

Thanks for sharing Josh 👍

josdejong avatar Jul 15 '22 11:07 josdejong