Javascript: Webpack+Typescript+Namespace (internal module) - javascript

We are trying to use Webpack to compile typescript code where we replaced “module” (now defined as external modules) with namespaces (defined as internal modules).
This change was done primarily to be in line with the recommendations of typescript and ensuring that dependency on “require” is not required for running Jasmine based unit tests on Karma. Karma-typescript preprocessor has been configured and the test case is running fine without the need of "require".
The change to namespace caused us to remove the dependency on require which works very well when it comes unit tests and compilation of the code through tsc. But on compilation through Webpack using typescript loaders (I’ve tried ts-loader, Webpack-typescript), the output contains code of just the entry ts file and not its dependencies. Tsc already has an option (--outFile) to concatenate the output into a single file but both the loaders do not use it.
Is there a way (loader or configuration of a loader) to resolve the dependency and bundle it into the single output js produced by Webpack?

This change was done primarily to be in line with the recommendations of typescript and ensuring that dependency on “require” is not required for running Jasmine based unit tests on Karma
You don't need to do that. You should use --module:commonjs everywhere and bundle for frontend + leave it as it is for running tests using node (node understands commonjs natively).
Example
I do this with alm https://github.com/alm-tools/alm/

Related

Test javascript in node's public folder using jest

I have a simple javascript function in an example.js file placed inside the node js public directory.
I am using jest for unit testing.
The problem is if I write the following in the example.js javascript file in the public folder:
module.exports.myFunction = myFunction;
Jest test file is able to import it, using require() and perform tests, however when I run the web application, the browser complains when I service the page containing this javascript:
Uncaught ReferenceError: module is not defined
What is the correct way to test javascript files in the public directory of the node application?
Using export and/or import in the project is reported an being unrecognized and results in errors as well.
How is this done?
As mentioned in comments require(...) and module.exports relate to Common JS Modules, which are natively supported by NodeJS runtime, but not by browser. So basically you'll need to add extra build configuration to have your module work in both runtimes.
If you want to have outputs in both CommonJs and Browser friendly bundle - you can write all code in ES Modules and use build tools like webpack to provide outputs in different formats.
Also, starting from Node 13.2.0 - it supports ES modules natively. So I would stick to ES modules for ongoing development anyway.
Please also check this short article on main JS module format differences.

Cordova build fails if I set 'type: modules' in package.json. How do I resolve this, yet still carry out unit testing?

I've built a simple app for Android, using the Cordova framework. I have now now implemented a simple unit test (using Tape), which runs in Node. Since the files I'm testing use ES6 modules, in order to run the tests in Node, I had to add "type": "module", to my package.json file. But when I did that, my app would no longer build--the Cordova build command fails with the output below. What is the proper way to resolve this issue?
Is it possible to programmatically set "type": "module",? If so, I can perhaps set it only when unit tests are running.
Or is some part of my method flawed in this case? That is certainly a possibility. Maybe if I test in the browser (rather than in Node), this issue will be avoided?
Thanks.
Build Output
$ cordova build android
Unable to load PlatformApi from platform. Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\Users\snarl\my-project\platforms\android\cordova\Api.js
require() of ES modules is not supported.
require() of C:\Users\snarl\my-project\platforms\android\cordova\Api.js from C:\Users\snarl\AppData\Roaming\npm\node_modules\cordova\node_modules\cordova-lib\src\cordova\util.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename Api.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from C:\Users\snarl\my-project\package.json.
Unhandled error. ('The platform "android" does not appear to be a valid cordova platform. It is missing API.js. android not supported.')
In case anyone else gets stuck on this, here is the solution I used (more of a workaround I guess). I bundled all files needed for unit testing into one single JS file--bundle-test.js--using Browserify (with a Babelify transform). Then I ran that file from the Node command line: node test-bundle.js. My unit tests ran without issue, and I didn't have to set "type": "module" in package.json.

Cannot use typescript class from other local typescript module using browserify

I have a common npm module containing TypeScript which is an node module providing some classes and functionality. This module is packaged via browserify + tsify and also exports the declaration files and built with gulp.
I have another npm module using TypeScript which imports this module locally via file:../modulename and tries to use functionality from the first module. The second module is also packaged via browserify + tsify and built with gulp. The compilation of the second module works via npx tsc, but fails if I execute the gulp build file with the error message
Error: Cannot find module './AbstractClass' from 'folderInOtherModuleContainingTheJSFiles'
Interestingly it sometimes fails with this Class sometimes with another, so it seems there is also some kind of concurrent processing.
I extracted the failing code from my project and created a minimal example with this behavior here.
npm version: 5.6.0
node version: v9.5.0
For anybody who might come to this post and face the same error.
I opened an issue at tsify too, thinking it has something to do with the plugin, because npx tsc worked.
Luckily the issue has been resolved, although with a workaround. There seems to be a name collision which causes browserify to think that a require call, which is a variable, in the resulting bundle needs to be resolved, but can't. The workaround is uglifying the resulting bundle, so that the conflict does not happen. More details in the above linked issue.

What is the difference between ng build and webpack

As I understand it, ng-build creates a distributable packaged version of your application. I also understand that webpack is used to bundle Javascript modules.
I ran ng build on a test project and found that it created a dist folder containing what looked like a packaged version of my Angular application. All of the .js files had been combined however my referenced .css files had been left in the original form (not bundled or minified).
Therefore, what is the difference between using ng build or webpack to do this job. Or are they complimentary? Would I potentially use both in my deployment pipeline?
Not a complete answer, but worth to note:
If your css files were not compiled, it probably means, either:
you ran ng build (a.k.a. ng build --dev) which adds default --extract-css to false:
--extract-css (aliases: -ec)
Extract css from global styles onto css files instead of js ones.
You ran ng build --prod but forgot to reference your styles as global styles in angular.cli.json:
"styles": [
"styles.css",
"assets/styles/test.component.css"
],
Once you do this you will find your css files inlined, however, you will also find them in normal format as well. Cant understand why is that..
Webpack and ng-build do pretty much the same job, which is bundling your modules to be used in a browser environment For example, the Angular module is a feature, which doesn't support in the browser, and ES 6 modules are not implemented in any browser yet, which is why things need to be bundled.ng build only for angular. we can you webpack any UI related applications including angular.

TypeScript compile .js

I want to use typescript in ES6-compatible mode, as a partial replacement for ES6 classes, because it is quite convenient and clear compiler, comparing to traceur/sweet.js macros.
How can I compile files with .js extension?
tsc src/util.js gives error TS5007: Cannot resolve referenced file: 'src/util.js', whereas tsc src/util.ts works just fine.
There are both util.js and util.ts in src directory, but I don’t want to have any .ts files.
You can't. It is intentionally not supported by the TypeScript compiler so as to avoid confusion for beginners.
However you can use the typescript compiler api, pass in your content and get the output you can write to file yourself.
There are plugins for grunt/gulp builders: gulp-typescript and grunt-typescript, which can make any sources, even non-.ts compiled with typescript.
Gulp-typescript implicitly uses typestring, which compiles any string with typescript code, and which is just a wrapper for the typescript.api - node.js API for typescript. Unfortunately, gulp-typescript is not fully complete - no errors logging, no compiling options, so you might need to use typescript.api straightaway.

Categories