Using relative path for templateUrl in Angular2+Webpack - node.js

import {Component} from 'angular2/core';
#Component({
selector: 'app',
styleUrls: ['./app.component.less'],
templateUrl: './app.component.html'
})
export class AppComponent {
name:string = 'Demo'
}
When using the relative path for templateUrl and styleUrls, I get: error 404, file not found:
zone.js: 101 GET http://localhost/app.component.html 404 (Not Found)
code: https://github.com/Dreampie/angular2-demo
I think this is not good design,because under different circumstances may build directory is not the same, can I change it to relative current path?
raw-loader can resolve this,but html-loader,less-loader not work for template,styles,it only work in string,so why not suport them?
import {Component} from 'angular2/core';
#Component({
selector: 'app',
styles: [require('./app.component.less')],
template: require('./app.component.html')
})
export class AppComponent {
name:string = 'Demo'
}
get other error:
browser_adapter.js:77 EXCEPTION: Error during instantiation of Token Promise<ComponentRef>!.BrowserDomAdapter.logError
browser_adapter.js:77 ORIGINAL EXCEPTION: Expected 'styles' to be an array of strings.

Let me add some more information.
Why can't Angular calculate the HTML and CSS URLs from the component file's location?
Unfortunately, that location is not readily known. Angular apps can be loaded in many ways: from individual files, from SystemJS bundles, or from CommonJS bundles, to name a few. With this diversity of load strategies, it's not easy to tell at runtime where these files actually reside.
The only location Angular can be sure of is the URL of the index.html home page. So by default it resolves template and style paths relative to the URL of index.html. That's why we previously wrote our CSS file URLs with an app/ base path prefix.
Official Angular Docu

The ./ (single dot) notation works for ts paths only, it doesn't work with html or css paths.
These paths are relative to index.html, so according to your file structure, this should work
#Component({
selector: 'app',
styleUrls: ['app.component.less'],
templateUrl: 'app.component.html'
})

You need to try
#Component({
selector: 'app',
template: require('./app.component.html'),
styles: [
require('./app.component.less').toString()
or
String(require('./app.component.less'))
or
add css-to-string in your webpack conf ({test: /\.css$/, loaders: ['css-to-string', 'style', 'css']})
})

Set the moduleId property to module.id for module-relative loading, so that urls are relative to the component.
#Component({
moduleId: module.id,
selector: 'app',
styleUrls: ['app.component.less'],
templateUrl: 'app.component.html'
})

If you are using SystemJS for example, see my answer here: https://stackoverflow.com/a/40694657/986160
You can use model.id and convert it from your build path (that with the js) to the one with ts,css and html. That way you can use relative paths for your templates and styles in Angular 2 no problem
#Component({
moduleId: module.id.replace("/dist/", "/"),
...
});

I have noticed the same error in my case. The reason of
Expected 'styles' to be an array of strings
in my case was css-loader which was used for loading CSS files and piped to angular2-template-loader.
What I understood from debugging that css-loader has some "smart" detection of changes in CSS files and if nothing were changed CSS file just wasn't exported as a string by webpack module.
As it was just hello word app my solution was very simple: replace css-loader by raw-loader. It is my version of loaders:
loaders: [
{
include: [srcPath],
test: /\.js$/,
loader: 'babel',
query: {
presets: ['es2015']
}
},
{
include: [srcPath],
test: /\.js$/,
loader: 'angular2-template-loader',
query: {
keepUrl: true
}
},
{
include: [srcPath],
test: /\.(html|css)$/,
loader: 'raw',
query: {
minimize: true
}
}
]

WebPack2 do not require this moduleId anymore

Related

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

Edit prefix when generate new angular 4 web app

I'm trying to edit prefix at component, service when generate new angular4 web app.I used options "--jhi-prefix" in command
jhipster --jhi-prefix my-prefix
but doesn't work.
In file app.module.ts
#NgModule({
imports: [
BrowserModule,
LayoutRoutingModule,
Ng2Webstorage.forRoot({ prefix: 'jhi', separator: '-'}),
In file navbar.component.ts
#Component({
selector: 'jhi-navbar',
templateUrl: './navbar.component.html',
styleUrls: [
'navbar.scss'
]
})
Please help me edit prefix 'jhi' to my custom prefix.

Loading a static file in Angular during build

I'm want to load the contents of a file and inject it as a string in TypeScript at build time. I understand that this code would ordinarily be server code, but what I want is to have a build step that reads the file and injects its contents as a string.
import { readFileSync } from 'fs';
import { Component } from '#angular/core';
#Component({
template: `<pre>${readFileSync('./example.code')}</pre>`
})
export class ExampleComponent { }
Assuming example.code just has "Hello World" I would want this file to be built as:
template: `<pre>"Hello World"</pre>`
I have found babel-plugin-static-fs which I think should allow me to do this, but I was originally using ng (angular-cli) to build the project. I have done ng eject and updated webpack:
module: {
rules: [
/* snip */
{
"test": /\.ts$/,
"use": [
{
loader: "babel-loader",
options: {
plugins: ['babel-plugin-static-fs']
}
},
{
"loader": "#ngtools/webpack"
}, ] } ] }
However, when I run webpack, I still get
Cannot find module 'fs'
If I reverse the order of the loaders, it seems like babael does not like the # used in may annotations such as the #Component above so that loader does not work.
Is there any way to load a file as static content during an Angular project build?
The issue here is actually related to the tsconfig.app.json file that Angular creates and uses for AoT. This is separate from the tsconfig.json used to actually build the project which does load #types/node as expected.
If you've created a project with ng new, you can change tsconfig.app.json:
- "types": [],
+ "types": ["node"],
This will have the AoT compiler use the type definitions from #types/node.

Import library into Angular2/WebPack project without NPM

I'm completely new to Angular2 and WebPack and am struggling with something probably very simple.
We're trying to incorporate yFiles for HTML into an Agular2/WebPack project. I've found and imported the types file on NPM at #types/yfiles. The rest of the library is only available from the vendor, not on NPM. This compiles correctly, but when I debug the project, the console reports the error:
EXCEPTION: Uncaught (in promise): Error: Error in ./HomeComponent class HomeComponent - inline template:0:0 caused by: yfiles is not defined
Error: Error in ./HomeComponent class HomeComponent - inline template:0:0 caused by: yfiles is not defined
It's not the HomeComponent so much as the DiagramComponent it references that's having the problem.
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'fs-diagram',
templateUrl: './diagram.component.html',
styleUrls: ['./diagram.component.scss']
})
export class DiagramComponent implements OnInit {
private canvas: yfiles.view.CanvasComponent;
constructor() {
this.canvas = new yfiles.view.CanvasComponent();
}
ngOnInit() { }
}
The folder structure looks like this:
> root
> .vscode
> node_modules
▼ src
> app
▼ lib
▼ yfiles
> impl
*.js
yfiles.css
> public
> style
main.ts
polyfill.ts
vendor.ts
npm-shrinkwrap.json
package.json
protractor.conf.js
tsconfig.json
tslint.json
typedoc.json
webpack.config.js
I get the feeling that the even though the #types/yfiles/index.d.ts file is present, it's looking for the *.js files at run time. Is that the problem, and if so, how do I import them into the project?
In order to have webpack include the yFiles modules in the bundle, they will indeed have to be imported in your Typescript file:
import yfiles = require("yfiles/view");
To make this work, webpack also needs to be told where the modules can be found - with webpack 2.x, this can be specified using the resolve.modules config in webpack.config.js:
module.exports = {
entry: "./src/index.ts",
output: {
filename: "dist/bundle.js"
},
resolve: {
extensions: [".ts", ".tsx", ".js"],
modules: ["./lib"] // the lib folder containing the yFiles modules
},
module: {
loaders: [
{ test: /\.tsx?$/, loader: "ts-loader" }
]
}
};

"You may need an appropriate loader for this file type", webpack can't parse angular2 file

I'm trying to get a very simple Angular2 app working, with Webpack as a module bundler. I'm following this code, and I copied all the configuration files as they are, only changing file paths. However, when I run npm-start, I get the following error, which I think is a Webpack error:
ERROR in ./hello.js
Module parse failed: /home/marieficid/Documentos/cloud/cloud/hello.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import {bootstrap} from "angular2/platform/browser";
| import {Component} from "angular2/core";
|
# ./app.ts 2:0-21
As a result, the Angular2 code in my app isn't loaded.
This is my app.ts:
import "./hello.js";
This is hello.js, where the error seems to be (which I take to mean that webpack parsed app.ts just fine):
import {bootstrap} from "angular2/platform/browser";
import {Component} from "angular2/core";
#Component({
selector: 'app',
template: '<div>Hello world</div>'
})
class App{}
bootstrap(App);
And this iswebpack.config.js:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
entry: {
'app': './app.ts',
'vendor': './vendor.ts'
},
output: {
path: "./dist",
filename: "bundle.js"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
new HtmlWebpackPlugin({
inject: false,
template: './index.html'
})
],
resolve: {
extensions: ['', '.ts', '.js']
},
module: {
loaders: [
{ test: /\.ts$/, loader: 'ts-loader' },
],
noParse: [ path.join(__dirname, 'node_modules', 'angular2', 'bundles') ]
},
devServer: {
historyApiFallback: true
}
};
All these files and node_modules are in the same directory.
I have found similar questions online but nothing worked for me. I also didn't install babel because the sample code I'm using as base doesn't use it, but if it's necessary I'm will.
As suggested by #napstablook
Since in your webpack.config.js file you have
resolve: {
extensions: ['', '.ts', '.js']
},
Webpack will try to handle those .js files but it needs a specific loader to do so which is, if I'm not wrong, script-loader.
In your case the solution is as simple as deleting the .js files, or changing their extension to be .ts.
For me this issue occurred when I ran ng test,
please check below points,
Console will list out the files that is causing the error.
Check the html file is correctly mapped from the typescript.
styleUrls file should point to the CSS file not html, this is the mistake I
did.
this error also comes up for me in angular forms when i had patch value set then an extra = sign
ncont.controls[position].patchValue({[cardname]:file}) = file
which is a dumb part on me and angular for not telling me

Resources