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

Angular CLI: VM package and process from node.js not available when targeting the browser (compile error) #135

Closed
tentone opened this issue Jun 15, 2020 · 13 comments
Assignees
Labels
documentation related to improving documentation

Comments

@tentone
Copy link

tentone commented Jun 15, 2020

Hello

When using the library inside of a typescript based project (in my case Angular) the vm library from nodejs cannot be found by the compiler.

The JS sandbox environment relies on this package to work. On the browser (unless using browserify with the browser-vm package) there is no way to get the code "compiling" properly, (at least if you compiler tries to solve every lib imported).

This could be solved if a method that does not rely on the vm lib was introduced in the lib.

Thanks a lot for working on this project.

Cheers

@tentone
Copy link
Author

tentone commented Jun 15, 2020

As i have been testing i found a way to run it without "errors" but i did need to do some changes to the lib. All of this should be easily fixable but splitting nodejs and browser user access points properly.

To avoid the "vm" not found error we can create a empty file and add it to the compilerOptions paths as if it was the vm lib in the tsconfig file.

	"compilerOptions": {
		...
		"paths": {
			"vm": ["./src/empty.ts"]
		},
	}

After this we get a Uncaught ReferenceError: process is not defined, that should also be easily fixable, but is an error since the process variable is not defined on browser environment.

To fix this one we actually need to change the files xlm.js, reportUtils.js, jsSandbox.js, processTemplate.js and main.js

var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;

change to

var DEBUG = false;

@tentone tentone changed the title VM package from node.js not available when targeting the browser (compile error) VM package and process from node.js not available when targeting the browser (compile error) Jun 15, 2020
@jjhbw
Copy link
Collaborator

jjhbw commented Jun 15, 2020

Hi, I think you make a great point.

Just to be sure, which version of docx-templates are you using?

The examples directory contains examples with webpack and browserify. Both of these compilers do a lot of magic under the hood. This makes building docx-templates for the browser look deceptively easy while it actually needs quite a bit of polyfilling, as you've shown.

I think we need to:

  1. Add an example for the Angular CLI. Also to be used as a test harness for this issue. Can you maybe give me a minimal example of what a vanilla Angular CLI setup looks like (without the workarounds you mentioned)?
  2. Ensure vm does not have to resolve at compile time. Adding a separate browser entrypoint may indeed be the best way to do this. I'll play around with this a bit.
  3. Remove the DEBUG hooks thingy. It is pretty much useless now anyway.

@jjhbw jjhbw self-assigned this Jun 15, 2020
@jjhbw jjhbw added the bug label Jun 15, 2020
@tentone
Copy link
Author

tentone commented Jun 15, 2020

Hello

I am using the last version from NPM published today 4.2.0.

Totally agree nowadays is a bit tricky to implement a solution compatible with all the solutions used to transpile/build js.

Aside from the changes i just pointed above, it is just import and use normally.

I can try and put together a PR with the changes required to fix these problems. If you want me to.

Once again thanks a lot great job

jjhbw added a commit that referenced this issue Jun 16, 2020
…presence of process.env outside of test code. Related to #135.
@jjhbw
Copy link
Collaborator

jjhbw commented Jun 16, 2020

Ok, clear!

I've removed the DEBUG flag.

I'm also working on an Angular example to add to the examples directory, see a883b0c

I'll check if I can make a few changes to how vm is required to make the project compile with a vanilla Angular compiler setup. If not, i'll use the example project to document the necessary compiler settings.

@tentone
Copy link
Author

tentone commented Jun 16, 2020

Hi

Thats great apart from the process that you already fixed the only change required is to separate the browser and nodejs access point to the library. In order for building systems targeting the browser to not try to solve the require("vm") call.

Otherwise the trick that i mentioned should work for any typescript project (not only angular). It just points the "vm" lib to a empty file making the compile be able to find it. It is not used in runtime anyway at least if you set noSandbox: true.

I would recommend to split the system into two methods one that uses require("vm") and other stuff from node to speed thing up and a second method using only browser available method.

Check this article out https://dev.to/riversun/recipes-on-how-to-create-a-library-that-supports-both-browser-and-node-js-201m should help with this.

There is also another option, you can build the library twice. One build using browserify that automatically translates nodejs stuff to browser compatible code. And a second time as is for node.js.

Once again thanks a lot!

@tentone tentone closed this as completed Jun 16, 2020
@tentone tentone reopened this Jun 16, 2020
@jjhbw
Copy link
Collaborator

jjhbw commented Jun 18, 2020

Alright, i've done some more digging.

It seems that besides vm, there's another NodeJS API, stream, that needs to be polyfilled/shimmed for browser use. stream is a dep of sax-js, the XML parser we use (see this issue). Shimming this in tsconfig.json the way you proposed for vm does not work, as sax-js tests for its existence the moment it is loaded.

Both these Node APIs are apparently cleanly shimmed by browserify/webpack. I didn't know the Angular CLI did so little magic in comparison... Hence, I think distributing a separate browserify build is the only way to thoroughly tackle this and make good on our 'browser compatible' promises. That should also allow users to use the whole thing without a transpiler.

@jjhbw
Copy link
Collaborator

jjhbw commented Jun 19, 2020

I'm currently deeply in JS toolchain hell.

I've transpiled the library using browserify and tsify and made a browser entrypoint (see the browserify-browser-build branch).

I'm testing whether importing the lib works in example-angularcli, but i'm getting an error. Note that angular app compilation succeeds: it is a runtime error.

Would appreciate it if you could take a look.

@tentone
Copy link
Author

tentone commented Jun 19, 2020

Sure, i will create a branch to test it and check the runtime error. To see if i'm able to figure our a way fix it somehow.

Thanks a lot!

@tentone
Copy link
Author

tentone commented Jun 19, 2020

Well, got the error to go away but the shim introduced by browserify for stream doesnt seem to be working. Probably and for now removing the DEBUG should be enough for it to work without any major configuration.

I will try during the weekend to come up with a better solution to this. Thanks a lot!

@jjhbw jjhbw added documentation related to improving documentation and removed bug labels Jun 22, 2020
@jjhbw jjhbw changed the title VM package and process from node.js not available when targeting the browser (compile error) Angular CLI: VM package and process from node.js not available when targeting the browser (compile error) Jun 22, 2020
@jjhbw
Copy link
Collaborator

jjhbw commented Oct 24, 2020

Closing this because resolving this is nontrivial and very specific to the angular toolchain. Feel free to reopen if you have a fix.

@jjhbw
Copy link
Collaborator

jjhbw commented Aug 6, 2021

@angelfraga
Copy link

angelfraga commented Aug 19, 2022

@jjhbw here I am facing the same issue with angular 12 webpack 5.

It seems Webpack 5 does not polyfill the node libs automatically like webpack 4 was doing.
eg: vm, utils ...

Since the sandboxjs library has vm-browserfy as dev dependency instead of a dependency we do not get installed it when installing docx-templates.

It can be solved by installing vm-browserfy as dev dependency and adding the path from vm to vm-browserfy.

But I guess in some point it should be marked as peerDependency in order to notify about this during the installation.

@mathe42
Copy link
Contributor

mathe42 commented Aug 19, 2022

You can also use the browser-ready-bundle see https://github.com/guigrpa/docx-templates#polyfilled-browser-ready-bundle this includes vm-browserfy.

BUT if you do the report-generation in a worker you don't block the Main-Thread and you can (also need to as vm-browserfy doesn't work in a worker) disable the sandbox (so no vm package needed).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation related to improving documentation
Projects
None yet
Development

No branches or pull requests

4 participants