"OuterSubscriber is not defined" when bundeling with rollup.js - javascript

After updating to Angular2 RC7 I get the folloing JavaScript error when running in the browser:
OuterSubscriber is not defined
This only happens when I create a bundle using rollup.js. If I run the application with the JavaScript not bundled it works fine.
The error must somehow be related with rxjs since OuterSubscriber is part of it. I checked the bundle and could not find OuterSubscriber there. I suppose rollup.js thinks that it is not necessary and therefore does not include it.
Environment:
angular, v2.0.0-rc.7
rxjs, v5.0.0-beta.12
systemjs, v0.19.27
gulp-rollup, v2.4.0
rollup-stream, v1.13.0
In the system.js config I map the umd modules (e.g. core.umd.js) for angular. For rxjs I use a classical mapping as in this example.
Does anyone have an idea what I'm doing wrong here?

Rollup 0.34.0 works with 2.0.0-rc.7 and verified Rollup 0.34.0 works with 2.0.0 also but I was able to replicate the issue with 0.35.0

There seem to be two problems with rollup currently.
rollup doesn't normalize slashes in paths ('/' vs '\\') and that issue is still open. To fix it rollup.config.js needs the following addition:
resolveId(id, from){
if (id.startsWith('rxjs/') || id.startsWith('rxjs\\')){
let result = `${__dirname}/node_modules/rxjs-es/${id.replace('rxjs/', '')}.js`;
return result.replace(/\//g, "\\"); // Add this
}
}
It breaks ES2015 code, but ES5 works fine, so it needs compiling rxjs-es to ES5 with ES2015 modules and making rollup resolver use it instead. Here is a separate tsconfig.rx.json:
{
"compilerOptions": {
"target": "ES5",
"module": "ES2015",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"skipLibCheck": true,
"outDir": "temp/rxjs",
"allowJs": true
},
"include": [
"node_modules/rxjs-es/**/*.js"
],
"exclude": [
"wwwroot",
"node_modules/rxjs-es/rx.js"
]
}
and rollup.config.js:
resolveId(id, from){
if (id.startsWith('rxjs/') || id.startsWith('rxjs\\')){
let result = `${__dirname}/temp/rxjs/${id.replace('rxjs/', '')}.js`;
//let result = `${__dirname}/node_modules/rxjs-es/${id.replace('rxjs/', '')}.js`;
return result.replace(/\//g, "\\");
}
}

Related

Typescript/Intellisesnse (wrongly?) picking up variable from another file (lib.dom.d.ts)

Today I referenced an unnamed/undefined variable but Typescript/Intellisense did not catch it, leading to a bug in my code. The variable name is "status", and Intellisense picked up the definition from the file /usr/share/code/resources/app/extensions/node_modules/typescript/lib/lib.dom.d.ts. (I am using Linux Ubuntu 20.04)
More details:
I initialized a basic project to demonstrate the error (Sorry I can't seem to post images because reputation is low)
unamed "status" variable does not create error
Upon clicking "Find all references", I found "status" has been declared in a random lib.dom.d.ts file
"status" has been declared in a random lib.dom.d.ts file
This seems to have been because I install Typescript globally? I also installed Typescript in the project; both installations are up-to-date with version "typescript#4.3.4"
I also checked if this is only a VSCode-specific bug, but Sublime Text's LSP-typescript also picked up the same wrong definition.
How do I solve this issue ?
My tsconfig.json is as followed
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"removeComments": true,
"strict": true,
"noImplicitAny": false,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"exlude": ["node_modules"]
}
The type definition is correct.
It's defined by window.status (although deprecated), so status should be considered a global in the browser context.
I ran into the same issue yesterday with close/window.close.
Thanks to #spender's answer, I realized that this is the expected behavior of Typescript, and it is me who have wronged.
I solved the issue by adding a "lib" option into my tsconfig.json. It seems that if I exclude the "lib" option, Typescript will default include all libs. But I don't want the "dom" lib to interfere with my backend code, so I use: "lib": ["es2015"]
If I ever use the "dom" lib in the future, I guess I will just have to be extra careful

VSCode Intellisense doesn't resolve imports with absolute paths

I'm maintaining an electron app using Typescript. I'm trying to implement absolute paths for imports in my project.
I understand that the way you would normally resolve this would be to edit webpack config, but since I'm using react CRA, and ideally don't want to "eject" and manage things myself just for this issue, I've been looking for other ways to solve the problem.
The intent is to go from something like this:
import * as Constants for '../../../../types/Constants'
to:
import * as Constants from '#types/Constants'
After reading through lots of articles, these are the steps I "think" I should be taking:
So far what I've done is:
Installed 'react-app-rewired' via NPM, and set up the config-overrides.js (to allow absolute imports to work).
Updated the tsconfig.json file (to allow VSCode to "see" the absolute imports)
(EDIT: Most of the steps I've tried come from absolute path with react, react-app-rewire and typescript)
//~config-overrides.js
module.exports = function override(config, env) {
config.resolve = {
...config.resolve,
alias: {
...config.resolve.alias,
'#types': path.resolve(__dirname, 'src/types')
}
}
return config;
Doing a console.log() of the config shows the alias field was set correctly. This allows the system to be aware of the imports via their absolute paths. Importing via the #types path operates as expected and I'm able to build, launch, and interact with my app without issue.
The problem arises with VSCode Intellisense, which marks all the absolute imports with the "red squiggly" and thus blocking things like autocomplete and being able to navigate to function/field definitions. I tried to resolve this by updating my tsconfig.json file thusly (specifcally adding the "extends" option and the referenced "tsconfig.paths.json" file):
// ~tsconfig.json
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"target": "ES2015",
"module": "esnext",
"allowJs": true,
"sourceMap": true,
"outDir": "./build",
"strict": true,
"noImplicitAny": false,
"esModuleInterop": true,
"preserveSymlinks": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"isolatedModules": true,
"noEmit": true,
"resolveJsonModule": true,
"jsx": "preserve"
},
"include": [
"src/backend/**/*.ts",
"src/backend/**/*.tsx",
"src/backend/**/*.js",
"src/electron.ts"
]
}
// ~tsconfig.paths.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"#types/*": ["./src/types/*"]
}
}
}
Possible issue:
When I build, I receive the following two error messages, and I don't know what to do with them:
compilerOptions.baseUrl must not be set (absolute imports are not supported (yet))
compilerOptions.paths must not be set (aliased imports are not supported)
EDIT:
I have a TSLint file in my project. Do I need to make any updates to that to make this work?

How to resolve "Definition for rule '#typescript-eslint/rule-name' was not found"

I'm trying to add TypeScript compilation to an existing Javascript project.
AFAIK this is supposed to be possible (even easy), and you can incrementally spread TS through the codebase. Unfortunately this isn't what I'm seeing - after adding typescript and trying to start the project, I get this error for every single file in the project:
Definition for rule '#typescript-eslint/rule-name' was not found
There is no instance of the string rule-name anywhere in my source code.
This is my tsconfig.json:
{
"compilerOptions": {
"baseUrl": "src",
"noImplicitAny": false,
"sourceMap": true,
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"esModuleInterop": true,
"jsx": "react",
"skipLibCheck": true
},
"include": [
"src",
"types"
],
"exclude": [
"node_modules",
"build"
]
}
I have tried adding "checkJs": false to the config and restarting but that doesn't change anything.
I haven't been able to track down anything online about this "rule-name" problem. It really looks like this is a placeholder text of some sort, but I can't find the source.
Can anybody suggest anything that might help me get this project to build?
The error that you have is coming from ESLint and means that you have a rule in your .eslintrc which doesn't exist in any of your plugins. This could have happened if you followed the usage guide for #typescript-eslint/eslint-plugin but didn't replace the placeholder rule-name with an actual rule name as seen here https://www.npmjs.com/package/#typescript-eslint/eslint-plugin
For those who do not want to just disable ESLint but make it work, running npm update could resolve the issue. In my case updating just #typescript-eslint/parser and #typescript-eslint/eslint-plugin was not enough but after npm update warnings dissapeared and ESLint was up and running.
Also worth to keep in mind this higlight from package authors:
It is important that you use the same version number for #typescript-eslint/parser and #typescript-eslint/eslint-plugin.
More detailed packages setup on npmjs.
This is because the rule is not declared in your eslint.json file
Add the following line to your RULES in esling.json file
"#typescript-eslint/object-curly-spacing" : "off"
Refer the image below to know more
Refer this image to add the rule to eslint.json file
For me, it was enough to add plugin:#typescript-eslint/recommended
in the .eslintrc file.
"extends": [
...<otherExtentions>...
"plugin:#typescript-eslint/recommended"
]
If you're using react-app-rewired and customize-cra, you need to make sure you use disableEsLint from the latter; otherwise linting errors become typescript errors and prevent compilation.

TypeScript Error Cannot find name on 'SyncClient' Twilio

I am creating an ionic app and everytime I try to use the library twilio-chat on my project via npm install I always got an error on .d.ts files
Import in my provider :
import { Client } from "twilio-chat";
Errors:
it seems the .d.ts files doesnt know where to look for the dependency modules they need. is it related on typings of typescript? I'm quite new to typescript.
but when I try to use the cdn it works perfectly fine.
I'm using
ionic: "3.18.0"
typescript: "2.2.1"
twlio-chat: "1.2.1"
update: I were able to fix the SyncClient and Emc Client by mapping on were exactly .d.ts files. the only problem was there are twilio dependencies that doesn't have .d.ts files like twilio-transport, twilsock and twilio-notifications.
tsconfig.json contains:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"dom",
"es2015"
],
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5",
"baseUrl": ".",
"paths": {
"twilio-sync": ["node_modules/twilio-sync/lib"],
"twilio-ems-client": ["node_modules/twilio-ems-client/lib"]
}
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
],
"compileOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
TIA
How do you compile typescript files? If you use tsconfig.json, make sure it uses "moduleResolution": "node" and node_modules can be found from upper directory. Maybe you want to look this: https://www.typescriptlang.org/docs/handbook/module-resolution.html#node
Twilio Developer Evangelist here. Let me see if I can help you :) Technically this should work right out of the box since both the twilio-sync as well as the twilio-chat library are written in TypeScript. Could you post your tsconfig.json as well as the full list of dependencies you have installed so that we can take a look at it?
In general you'll have to install typings for any module that doesn't ship it's own typings.
Cheers,
Dominik

Angular 2 AoT Rollup fails with 'require is not defined'

I have and Angular2 application that I'm compiling to run with AoT.
I've solved the issues I had with the actual compilation and I've also been able to run Rollup from start to end without errors (although there's a lot of warning, which I think are to be expected).
However, when running the application, the browser always states that require is not defined on my app.bundle.js.
What am I doing wrong?
Here's my functional non-AoT sample code/configs:
https://plnkr.co/edit/oCAaeXUKWGyd34YKgho9?p=info
And here is my functional AoT sample configs that throw the require error:
https://plnkr.co/edit/Y1C5HaQS3ddCBrbRaaoM?p=info
Does anyone find any errors here, especially when comparing the non-AoT system.js configs and the AoT rollup configs?
Why am I hitting this error?
I understand that the browser is incapable of working with require but shouldn't rollup attend to that?
Best Regards
So, eventually I was able to solve the issue.
There was a rogue const _ = require("lodash") in the code.
Once I removed it, it all went along without issues.
Two things worth mentioning:
Due to memory limitations on node.js (1.7GB of RAM), the ngc command is run with node --max-old-space-size=8192 ./node_modules/.bin/ngc -p tsconfig-aot.json
Again, for the same reason, rollup is run with node --max-old-space-size=8192 ./node_modules/.bin/rollup -c rollup-config.js
You might be able to get away with --max-old-memory=4096, depending on the size of your project and memory on your computer.
As for my rollup-config.js, though I'm not sure if everything here is really necessary, here's what worked for me:
import builtins from 'rollup-plugin-node-builtins';
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify';
export default {
entry: 'app/app.aot.js',
dest: 'www/bundle.js', // output a single application bundle
sourceMap: false,
format: 'iife',
plugins: [
nodeResolve({
jsnext: true,
module: true,
browser: true
}),
commonjs({
// non-CommonJS modules will be ignored, but you can also
// specifically include/exclude files
include: [
'node_modules/**',
'node_modules/primeng/**',
'node_modules/moment/**',
'node_modules/rxjs/**',
'node_modules/lodash/**'
], // Default: undefined
exclude: ['node_modules/ws/**'], // Default: undefined
// search for files other than .js files (must already
// be transpiled by a previous plugin!)
extensions: ['.js'], // Default: [ '.js' ]
// if true then uses of `global` won't be dealt with by this plugin
ignoreGlobal: false, // Default: false
namedExports: {
// left-hand side can be an absolute path, a path
// relative to the current directory, or the name
// of a module in node_modules
'node_modules/primeng/primeng.js': [
'PanelModule',
'InputSwitchModule',
'InputMaskModule',
'ProgressBarModule',
'DropdownModule',
'CalendarModule',
'InputTextModule',
'DataTableModule',
'DataListModule',
'ButtonModule',
'DialogModule',
'AccordionModule',
'RadioButtonModule',
'ToggleButtonModule',
'CheckboxModule',
'SplitButtonModule',
'ToolbarModule',
'SelectButtonModule',
'OverlayPanelModule',
'TieredMenuModule',
'GrowlModule',
'ChartModule',
'Checkbox',
'Dropdown',
'Calendar',
'DataGridModule',
'DataTable',
'MultiSelectModule',
'TooltipModule',
'FileUploadModule',
'TabViewModule',
'AutoCompleteModule'
],
'node_modules/ng2-uploader/index.js': ['Ng2Uploader']
},
// if false then skip sourceMap generation for CommonJS modules
sourceMap: false, // Default: true
}),
builtins(),
uglify()
]
}
rollup still complains about default imports on some packages, which can be probably solved using the named exports (if you really want to) but even with those warnings everything seems to be running.
As for my "final" tsconfig.json:
{
"compilerOptions": {
"lib": ["es2015", "dom"],
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"declaration": false,
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"watch": false,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"suppressImplicitAnyIndexErrors": true,
"baseUrl": ".",
"typeRoots": [
"./node_modules/#types",
"./node_modules"
],
"types": [
"node",
"lodash",
"jasmine",
"bluebird",
"socket.io-client"
]
},
"compileOnSave": false,
"buildOnSave": false,
"files": [
"app/app.module.ts",
"app/app.aot.ts"
],
// "exclude": [
// "node_modules"
// ],
"angularCompilerOptions": {
"genDir": "compiled",
"skipMetadataEmit": true
}
}
Finally, these two links were also helpful in understanding what's going on behind the scenes:
https://code.lengstorf.com/learn-rollup-js/
https://github.com/rollup/rollup/issues/737
Hope this helps someone.
My solution for this problem was the following:
I tracked, what the system wants to require: the modules fs, events, and timer. All of them were referenced in the zone.js.
I've found some zone.js imports hacked into my code in my earlier tries to make in smaller as 5M.
After I removed them, the problem disappeared.
For the googlers of the future with a similar problem:
The cause of the problem is that your npm module uses require() internally. You have to update it, or to recompile it, but this time as ES6 package (which doesn't use require(), it uses import). If a require is really deeply hardcoded into it (for example, it is in .js and uses require), then you have to modify its source.
Additional extension:
It seems, rollup can't correctly handle non-ordinary imports like import 'Zone.js'; and similar! It can handle only import { something } from 'Anything';-like imports!
The root of all problems is that Angular requires zonejs imported on this way, furthermore any typescript decorator require the reflect-metadata package, imported also on this way.
But, it is not really a problem. Things looked so before, like
<script src="...zone.js"></script>
Or with an
import 'zone.js';
, shouldn't be exist in the source (or in the HTML) any more. Instead, you have to compile the sources without them, and then simply concatenate them to the beginning of your source. In my case, I use the following Grunt rule:
concat: {
dev: {
src: [ "node_modules/zone.js/dist/zone.js", "node_modules/reflect-metadata/Reflect.js", "target/MyApp-core.js" ],
dest: "target/MyApp.js"
}
},
It is part of the grunt-contrib-concat Grunt package.
The resulting target/MyApp.js can be further processed by any other tools (uglify, or the best is google closure compiler).

Categories