Navigation Error in angular2 - node.js

I have updated the angular packages version from 2.4.10 to 4.0.0 after updating i am getting the following errors while navigating.
ERROR Error: Uncaught (in promise): Error: Found the synthetic property #transformPlaceholder. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.
Error: Found the synthetic property #transformPlaceholder. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application
And i changed the webpack.common.js configuration. see the below code
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)#angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),

I have fixed the issue. I added a new package: #angular/animations.
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
And I imported the module:
#NgModule({
imports: [
BrowserAnimationsModule
]
})

It's a change from 4.0.0-rc.1.
In their words, "We have pulled Animations into their own package. This means that if you don’t use Animations, this extra code will not end up in your production bundles. This also allows you to more easily find documentation and to take better advantage of autocompletion. If you do need animations, libraries like Material will automatically import the module (once you install it via NPM), or you can add it yourself to your main NgModule."
npm install #angular/animations --save
Inside AppModule >> import {BrowserAnimationsModule} from '#angular/platform-browser/animations'
Add it to imports.
#NgModule({
imports: [
BrowserAnimationsModule
]
})

That depends on whether you want to use Angular animations or not
In case you do not want to use it (i.e. it will reduce the production bundle size) then import the NoopAnimationsModule :
import { NoopAnimationsModule } from '#angular/platform-browser/animations';
imports: [
NoopAnimationsModule
// ...
]

One can run into a problem with
import {BrowserAnimationsModule} from '#angular/platform-browser/animations';
You can get this error message:
node_modules/#angular/platform-browser‌​/bundles/platform-br‌​owser.umd.js/animati‌​ons 404 (Not Found)
To fix it, if you are using systemjs.config.js then you need to have this line it it:
'#angular/platform-browser/animations': 'npm:#angular/platform-browser/bundles/platform-browser-animations.umd.js',
Here is example contents of systemjs.config.js that fixes the problem:
/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/router/upgrade': 'npm:#angular/router/bundles/router-upgrade.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
'#angular/animations': 'npm:#angular/animations/bundles/animations.umd.js',
'#angular/animations/browser': 'npm:#angular/animations/bundles/animations-browser.umd.js',
'#angular/platform-browser/animations': 'npm:#angular/platform-browser/bundles/platform-browser-animations.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'primeng': 'npm:primeng'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
primeng: {
defaultExtension: 'js'
}
}
});
})(this);
Note: The references to primeng are not necessary unless you are using it. I happen to be giving it a try. (Not a recommendation)

Don't forget to add the following line in your System.config.js file. If you are going to use animations in your angular project then you need to include this lines in your angular repo.
'#angular/animations': 'npm:#angular/animations/bundles/animations.umd.js',
'#angular/animations/browser': 'npm:#angular/animations/bundles/animations-browser.umd.js',
#angular/platform-browser/animations': 'npm:#angular/platform-browser/bundles/platform-browser-animations.umd.js',

Related

Bundle NPM Package so it has different import paths with Vite and Typescript

How can I bundle my NPM package in a way that I can have different import paths for different parts of the package? I have found webpack approaches, but I am using Vite and TS.
My package looks like this:
- src
- atoms
- molecules
- organism
- index.ts (currently simply imports and exports everything)
Now I can use this currently like this
import { Button } from '#mypackage/library'
How can I do it, so I get this outcome:
import { Button } from '#mypackage/library/atom'
Here is the relevant part of my package.json
{
"entry": "src/index.ts",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"exports": {
".": {
"import": "./dist/index.es.js",
"require": "./dist/index.cjs.js",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json",
"./atoms": "./src/atoms/index.ts",
"./molecules": "./src/molecules/index.ts",
"./organisms": "./src/organisms/index.ts",
"./theme": "./src/theme/index.ts"
},
}
Here is my vite.config.ts
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
formats: ['es', 'cjs'],
name: '#workdigtital/component-library-react',
fileName: (format) => `index.${format}.js`
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM'
},
exports: 'named'
}
}
},
plugins: [react(), dts({ insertTypesEntry: true })],
resolve: {
alias: {
'#': path.resolve(__dirname, './src')
}
}
});
If I currently try an import like this, inside another project (Laravel+React), in which installed the library.
import { ThemeProvider } from '#workdigital/component-library-react/theme';
I get the following run time error (But no Typescript errors, even IntelliSense is working):
Failed to load url /resources/js/theme/ThemeProvider (resolved id: /resources/js/theme/ThemeProvider). Does the file exist?
My resulting Dist folder looks like this:
You can't have TypeScript exports, this simply won't work. An npm package should have only JS exports.
If you want to be able to selectively import different parts of your package, you must transpile them to different files.
rollup can do it, but it is lots of work, as you will have to set up a separate target for each exported file. Normally you use rollup to create a single bundle, this what this tool is made for.
tsc with a tsconfig.json will be a much better choice in your case. It does this by default, you only need to specify the output directory and it will produce a separate file for each source.
There is an excellent guide on the TypeScript site about packaging TypeScript libraries, you should probably start there.

Vite library with Windicss

I am using Vite (Vue3) with Windi CSS to develop a library. I am using library mode for the build (https://vitejs.dev/guide/build.html#library-mode) with the following config:
vite.config.js
export default defineConfig({
plugins: [vue(), WindiCSS()],
build: {
lib: {
entry: path.resolve(__dirname, 'src/lib.js'),
name: 'MyLIB',
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue',
},
},
},
},
});
My entry file (src/lib.js) only includes a few Vue components in it and looks like this:
lib.js
export { default as AButton } from './components/AButton/AButton.vue';
export { default as ACheckbox } from './components/ACheckbox/ACheckbox.vue';
import 'virtual:windi.css';
import './assets/fonts.css';
When I build the library I get the js for just those components but the css is for every Vue file in the src folder and not only the ones i included in my lib.js file. I know the default behavior for Windi CSS is to scan the whole src folder but in this case, I only want it to scan the components I added to my entry.
Any ideas?
You should be able to restrict the scan by using extract.include and extract.exclude options, see there : https://windicss.org/guide/extractions.html#scanning
From the doc
If you want to enable/disable scanning for other file-types or locations, you can configure it using include and exclude options

Node.js: How to import test files in custom test runner

I'm trying to create my own custom testing framework for learning purpose. Test files are written in following way
import { somemethod } from './some/module'
test(/I click on a button)/, () => {
browser.get("someSelector").should("have.text",somemethod());
});
I user require(file) to load test files. But it throw error SyntaxError: Unexpected token {
for import statement in test file. I'm using node js version 11.15.
If I switch to node v13.14 and define "type": "module" in my package.json then it doesn't let me use require(file) to load a test file or any module in my package.
How can I import tests files considering the user may be importing the modules using import or require?
This answer is very empirical...
Considering that it works using canonical commonjs approach you can try to debug it with newer version of NODE (currently I would use 14). For it, I would suggest you to use a node version manager like NVM so you can switch between node version easily and test that accordling seeing differences between various node installations.
Make a minimal project with npm init with a single dependency, save your index with the .mjs extension and try an import the above dependency. If you are be able to import that dependency with that minimal environment you can blame either your previous node or your configuration or both of them.
At the moment you should only create a small 2 files project to reproduce the problem. It seems your current node does not consider the "type": "module" configuration and runs everything in its classic way.
Regarding your comments....
As far as I know import can be used even in your code, not just at the beginning:
(async () => {
if (somethingIsTrue) {
// import module for side effects
await import('/modules/my-module.js');
}
})();
from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Additionally you can try Webpack with a configuration like:
// webpack.config.js
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'production',
target: 'node',
externals: [nodeExternals()],
entry: {
'build/output': './src/index.js'
},
output: {
path: __dirname,
filename: '[name].bundle.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
'targets': {
'node': 'current'
}
}]
]
}
}
}]
}
};
With NodeExternals you don't put your node dependencies in the bundle but only your own code. You refer to node_modules for the rest. You might not want that.

How to use vuetify in nuxt js as plugin?

I need to use vuetify in my nuxt js project as plugin. I've tried package #nuxtjs/vuetify but get error
Cannot assign to read only property 'base' of object '#'
I've install my nuxt project from official codesandbox online playground in local server and on shared hosting. All the time I got the same error. I tried install node modules using npm and yarn. How I can add fresh vuetify version to last version of nuxt js as plugin with npm package vuetify?
Install vuetify and #mdi/font
Create a file vuetify.js in your plugins folder with the following code:
import Vue from 'vue'
import Vuetify from 'vuetify'
import colors from './../config/colors'
import 'vuetify/dist/vuetify.min.css'
import '#mdi/font/css/materialdesignicons.css'
Vue.use(Vuetify)
export default ctx => {
const vuetify = new Vuetify({
theme: {
themes: {
light: {
...colors
},
dark: {
// colors
}
}
}
})
ctx.app.vuetify = vuetify
ctx.$vuetify = vuetify.framework
}
Edit nuxt.config.js file by adding vuetify to plugins like this
{
...
plugins: ['~plugins/vuetify.js'],
...
}
I achieved this with the following:
npm install --save vuetify
create a file vuetify.js in your plugins folder with the following code:
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)
Amend your nuxt.config.js:
plugins: ['~plugins/vuetify.js'],
build: {
vendor: ['vuetify']
}
There is a discussion of this issue here: https://github.com/nuxt-community/vuetify-module/issues/268
Fixing custom colours and specifying options in external files seem to affect this.
If you have colours specified in the options, replace primary: colors.blue with primary: colors.blue.base.
I have / had same issue. I simply made sure to use version 1.10.3 or below defined explicitly in package.json
"#nuxtjs/vuetify": "1.10.3", (not with the ^1.10.3)
I also noticed any version over this also adds an "undefined" 404 to the end of every url request. I posted on Nuxt / CMTY but they have a user base of zero people who answer any questions.
Choose Vuetify as ur UI Framework when initial a Nuxt project
Create a new file in plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify'
import colors from 'vuetify/es5/util/colors'
Vue.use(Vuetify)
export default new Vuetify({
theme: {
light: true,
themes: {
light: {
primary: colors.blue.darken2,
accent: colors.grey.darken3,
secondary: colors.amber.darken3,
info: colors.teal.lighten1,
warning: colors.amber.base,
error: colors.deepOrange.accent4,
success: colors.green.accent3
}
}
}
})
Add the plugin config inside nuxt.config.js
export default {
plugins: ['~/plugins/vuetify.js'],
}
Restart server, npm run dev
An image example:
vuetify.js
Done!
you can do the following steps in order and finally use Vuetify components:
1- Setup vuetify
yarn add vuetify#next sass
2- Your package.json should now look similar to the following:
// package.json
"devDependencies": {
"nuxt": "3.0.0-rc.1"
},
"dependencies": {
"sass": "^1.51.0",
"vuetify": "^3.0.0-beta.1"
}
3- Creating your Vuetify plugin
You must create this file in the plugin folder and put these codes inside it.
// plugins/vuetify.js
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
export default defineNuxtPlugin(nuxtApp => {
const vuetify = createVuetify({
components,
directives,
})
nuxtApp.vueApp.use(vuetify)
})
4- Configure Nuxt 2 or 3 to use our new plugin
In this section, you should put these codes in the nuxt.config.ts file like this
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
css: ['vuetify/lib/styles/main.sass'],
build: {
transpile: ['vuetify'],
},
vite: {
define: {
'process.env.DEBUG': false,
},
},
})
5- Finally, in order to test that you have done the steps correctly, you can use this component in your code to see if Vuetify is installed correctly or not.
<v-btn>Button</v-btn>
Tip: If you have done these steps or you want to use a new component, in many cases it is better to stop and restart your project once.

Parsing XML in typescript

Using Typescript 2.0 (tsc version 2.0.3).
I have unsuccessfully attempted to use the xml2js node library inside an angular2/typescript application (see https://www.npmjs.com/package/xml2js). Seems clear I am not familiar enough with the way the SystemJS sets up the library for consumption.
To install the xml2js library I did the following:
npm install --save xml2js
npm install --save #types/xml2js
Here are the relevant files:
tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir" : "build"
}
}
systemjs.config.js
/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'build',
// angular bundles
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
'#angular/upgrade': 'npm:#angular/upgrade/bundles/upgrade.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'lodash' : 'npm:lodash',
'xml2js' : 'npm:xml2js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
lodash: {
main : 'index.js',
defaultExtension: 'js'
},
xml2js: {
defaultExtension: 'js'
}
}
});
})(this);
The consuming file:
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/Rx';
import * as _ from 'lodash';
import * as xml2js from 'xml2js';
#Injectable()
export class CatalogService {
constructor (private http:Http) {
}
getCatalog() {
//return Promise.resolve(['This', 'That']);
var xml = "<root>Hello xml2js!</root>"
xml2js.parseString(xml, function (err, result) {
alert(result);
});
alert(_.indexOf([1, 2, 1, 2], 2));
}
}
index.html file
<html>
<head>
<title>Angular QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- 1. Load libraries -->
<!-- Polyfill for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body>
<dsa-app>Loading DSA App...</dsa-app>
</body>
</html>
With that setup, I do get an error as follows:
zone.js:1382 GET http://localhost:3000/node_modules/xml2js/ 404 (Not Found)
The lodash library loads fine, so I am pretty sure the issue here has to do with the way the xml2js library is defined more than my setup.
Closest solution I have seen for this is a bit dated for Angular 2.0, but I put it here for reference: Use JS library xml2js with Angular 2
Although the question specifically addresses using that library, any other ideas on how to parse/convert xml into something manageable inside TypeScript would also come in handy.
Update:
As suggested I started adding "main" definitions to my systemjs configuration. However, I though part of this was that the dependencies would be loaded/figured out from the node content.
Thus modifying the system.config.js to have:
xml2js: {
main: 'lib/xml2js.js',
defaultExtension: 'js'
},
Move the issue to where now I get 404 entries for sax and xmlbuilder.
Thus, I added the following too:
sax: {
main: 'lib/sax.js',
defaultExtension: 'js'
},
xmlbuilder: {
main: 'lib/index.js',
defaultExtension: 'js'
}
Which address the sax and xmlbuilder, but then more errors popup.
I thought the whole idea with using the SystemJS and the tsconfig would be that these would be figured out from the node modules, adding all the tree dependencies on the packages seems to defeat the purpose.
I think the issue here is in your systemjs config - you haven't defined main for xml2js. Because of that systemjs doesn't know which file to load, so tries to load the NPM directory directly for some reason (loading /node_modules/xml2js as a file, which clearly isn't going to work). Note that your lodash config does specify 'index.js', presumably leading to /node_modules/lodash/index.js being loaded when you import lodash, which is why that works.
If you specify a 'main' for xml2js in your systemjs config that pointing to lib/xml2js.js then systemjs should be able to find it correctly.
As noted by #tim-perry, the issue here was the way the package was defined.
A further issue in my work is that I was making wrong assumptions about what SystemJS would do for me. I need to look into a different tool (starting with JSPM) that would do the tree walk when loading the base module. In my example, lodash was working because it is self contained. However, xml2js had a lot of dependencies, that had a lot of dependencies, that had a lot of dependencies ... thus applying the solution of adding the package definition for each dependency took care of the issue albeit in a very cumbersome way.
Again, thanks to #tim-perry and #artem who helped with this.

Resources