How to use mvc page as angular 5 templateUrl - asp.net-mvc

I am migrating my old project that used systemjs, to start use webpack, but now i having problems with the loading of templateUrl.
My old project use mvc views on templateUrl property of angular componentes, but with my new project this not work.
When i use the templateUrl calling a html file, all work good.
#Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
But, when i call a mvc route that provide a page, not work. (The route are work if you write manually in the browser)
#Component({
selector: 'app',
templateUrl: '/Teste/Index',
styleUrls: ['./app.component.css']
})
My mvc controller class:
public class TesteController : Controller
{
public IActionResult Index()
{
return View();
}
}
So, i need load my mvc views as templateUrl, can anyone help me ?

This can be done, it requires using your own webpack configuration rather than angular-cli, so that you can use one of the standard typescript compilers in webpack that won't try to access the templateUrl path at build time.
Assuming that you are currently using angular-cli to build your angular app (you haven't mentioned your current configuration?) then you'd need to eject the angular-cli config so that angular creates a webpack.config.js file, then you can go about altering the configuration to suit your needs.
The following 2 commands will get you out of angular-cli and ready to use webpack directly (if you are on angular 6 then I think the eject functionality may have been disabled but it should work with angular 4/5):
ng eject tells Angular CLI to generate the webpack.config.js file
npm install then installs new dependencies required to use the webpack config directly to build your app.
You'll need to then go through the webpack.config.js and make changes for it to work for you (you'll need to read up on webpack quite a bit as when you first go through it most of it won't make much sense but it's worth getting your head around so you can configure it properly), for the mvc views to work you'll need to alter the modules configuration, updating the loader for typescript files (we use ts-loader as it offers extensions that allow for faster builds with threading to speed things up but there are others out there as well) and adding a loader for html / cshtml files.
Below is a snippet of our configuration that has us using mvc view paths for component templates:
module: {
rules: [
{
test: /\.aspx$/i,
loader: 'raw-loader'
},
{
test: /\.(cs)?html$/,
loader: 'raw-loader'
},
{
test: /\.(eot|svg|cur)$/,
loader: 'file-loader',
options: {
name: '[name].[hash:20].[ext]',
limit: 10000
}
},
{
test: /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
loader: 'url-loader',
options: {
name: '[name].[hash:20].[ext]',
limit: 10000
}
},
{
test: /\.ts$/,
use: [
{ loader: 'cache-loader' },
{
loader: 'thread-loader',
options: {
// there should be 1 cpu for the fork-ts-checker-webpack-plugin
workers: require('os').cpus().length - 1
}
},
{
loader: 'ts-loader',
options: {
happyPackMode: true // IMPORTANT! use happyPackMode mode to speed-up compilation and reduce errors reported to webpack
}
},
]
},
{
test: /\.(ts|js)$/,
loaders: [
'angular-router-loader'
]
}
]
}
It's a bit of a painful process but it can definitely be done.
Bear in mind that with this configuration, you won't be able to use AOT compliation to improve performance...

Related

I'm getting an error building a sveltekit project

I'm building a sveltekit project. One thing I've done is created a custom type of file which is converted to a *.svelte file upon building or running the development server. By default, sveltekit includes the rollup extension rollup-plugin-dynamic-import-variables which is trying to parse my custom file (who knows why?) and throwing an "unexpected token" error. I'm trying to configure that extension to ignore my custom files, but so far without success. Here is my attempted svelte.config.js file:
// #type {import('#sveltejs/kit').Config}
var config;
import adapter from '#sveltejs/adapter-static';
import dynamicImportVariables from 'rollup-plugin-dynamic-import-variables';
config = {
kit: {
// --- hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: null
}),
vite: {
plugins: [
dynamicImportVariables({
warnOnError: true,
exclude: '**'
})
]
}
}
};
export default config;
To be honest about it, I don't use dynamic imports anywhere and therefore would accept as a solution the complete disabling of the extension. But anything that would get it to ignore my custom files would also work.
UPDATE: SvelteKit 1.0.0-beta now requires pages/endpoints to follow a specific naming pattern, so explicit file exclusion should no longer be needed.
SvelteKit specially handles files in the routes/ directory with the following filenames (note the leading + in each filename):
+page.svelte
+page.js
+page.server.js
+error.js
+layout.svelte
+layout.js
+layout.server.js
+server.js
All other files are ignored and can be colocated in the routes/ directory.
If, for some reason, you need to have a file that has a special name shown above, it's currently not possible to exclude that file from special processing.
Original outdated answer:
The rollup-plugin-dynamic-import-variables is actually included by Vite. To configure Vite's plugin, set the build.dynamicImportVarsOptions property:
// svelte.config.js
/** #type {import('#sveltejs/kit').Config} */
const config = {
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: "#svelte",
vite: {
build: {
dynamicImportVarsOptions: {
exclude: [/node_modules/, /\.starbucks$/],
},
},
},
},
}
export default config
But that's not going to fix the problem...
SvelteKit processes all files under src/routes/ so that they're automatically imported in the output application (in .svelte-kit/build/app.js), which will result in the same error.
Option 1: Private modules
You could exclude a src/routes/*.starbucks file by making it a private module, which has a leading underscore in the filename:
src/routes/_home.starbucks 👈
src/routes/_index.starbucks 👈
src/routes/index.svelte
Option 2: Move files outside src/routes
Alternatively, move those *.starbucks files outside of src/routes/ (e.g., into src/starbucks/ or src/lib/):
src/routes/index.svelte
src/starbucks/home.starbucks 👈
src/starbucks/index.starbucks 👈
src/lib/home.starbucks 👈
src/lib/index.starbucks 👈

How do I add an additional postcss plugin via the new #angular/cli v7 angular.json or custom-webpack.config.js?

#angular/cli#7+ allows a customWebpackConfig to be specified to provide custom webpack configuration, such as:
"architect": {
"build": {
"builder": "#angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./build/custom-webpack.config.js",
"mergeStrategies": {
"externals": "prepend"
}
},
...
This file then technically allows you to prepend, append or replace any portion of the webpack configuration. Prior to upgrading to #angular#7.1.3 and #angular/cli#7.1.3 we had ejected the webpack configuration to make some additions. One such addition was the postcss-momentum-scrolling postcss-loader plugin that automatically enabled iOS momentum scrolling on all scrollable containers.
I am seeking support on figuring out how to generate the necessary custom webpack code to load this plugin via the supported customizations allowed by #angular/cli#7+.
Here is a sample of what I have tried in my custom-webpack.config.js file:
const postcssMomentumScrolling = require('postcss-momentum-scrolling');
module.exports = {
module: {
rules: [
{
test: /\.scss$|\.sass$/,
use: [
{
"loader": "postcss-loader",
"options": {
"plugins": [
postcssMomentumScrolling(),
]
}
}
]
},
],
},
};
As soon as I touch the scss chunk of the webpack config, it seems to do a replace instead of a merge or prepend, breaking the build.
I am wondering if anyone has a guide or suggestions on how to see what the initial webpack configuration that #angular/cli generates that is the starting point for modifications and a way to preview/peek at the code to be executed as debugging.
Also, an example of a similar customization would be great.
Thanks!
I think you need to tell to "customWebpackConfig" which portion to merge. Like this:
"mergeStrategies": {
"module.rules": "prepend"
}
In this way you're going to tell to merge with prepend strategy.
According to "custom-webpack" documentation it should default to "append" which doesn't seem the case in your example.
It's been a while since you've put the question but I wanted to actually ask if you have been able to fix it since I'm running in some issues getting my "module.rules" merged...it seems to work only if I set "replace" strategy.

Rails 5.1 Angular templateUrl

Question
What do I need to do to get my Angular application to allow me to use the templateUrl property of the Component decorator? When you create a new Rails 5.1 application and use the flag --webpack=angular, it gives you a proof of concept Angular application, but as soon as I started creating more components, I began to recognize that I don't know how to refer to the correct path that the templates are being served. I'm not even sure if they are being served, to be honest.
What I've tried
Tried many different variations of the path, from just the file name all the way to the root of the application, one folder at a time.
Googling for someone else running into the same problem.
include the CommonModule in my imports in app.module.ts.
Background
I'm really used to using the Angular CLI and I don't remember ever having an issue using the templateUrl property. What is different about an Angular CLI project to what's given to you in a Rails 5.1 app in terms of configuration affecting templates? Would I be able to use Angular CLI in a Rails 5.1 app without having to change much of the Rails app itself?
Can be done. But this needs a different webpack loader setup and several minor tweaks.
But first: shopping!
$ yarn add \
html-loader \
awesome-typescript-loader \
angular2-template-loader \
#types/node \
--dev
With all required packages installed replace config/webpack/loaders/angular.js with this:
const {env} = require('../configuration.js');
isProd = env.NODE_ENV === 'production';
module.exports = {
test: /\.ts$/,
use: [
{
loader: 'awesome-typescript-loader',
options: { useCache: !isProd }
},
'angular2-template-loader'
]
};
angular2-template-loader scans your Component decorators for the templateUrl argument and replaces it with something like template: require('...')'. The require() call is the reason for installing #types/node by the way.
awesome-typescript-loader is a bit more optimized than the default ts-loader (which will probably work here as well, but I didn't test it).
So far so good. Next we need to tell webpack how to actually load HTML files. Add config/webpack/loaders/html.js with the following content:
module.exports = {
test: /\.html$/,
loader: 'html-loader',
};
Nothing obscure here. Moving on.
In your Javascript app add type informations for *.html files to app/javascript/hello_angular/html.d.ts:
declare module "*.html" {
const content: string
export default content
}
This tells the TypeScript compiler that require('template.html') returns a string.
Last but not least you have add .html to the recognized extensions in config/webpacker.yml:
default: &default
# ...
extensions:
# ...
- .html
# ...
Now you should be good to go:
import { Component } from '#angular/core';
#Component({
selector: 'hello-angular',
templateUrl: './template.html'
})
export class AppComponent {
name = 'Angular!';
}
Don't forget to restart bin/webpack-dev-server.
Theoretically you could do the same for styleUrls. But this is more tangled with rails/webpacker and you would loose some of it's features.

Webpack 2: CommonsChunkPlugin issue

I would like to ask a question about CommonsChunkPlugin
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
vendor: ['moment'],
app: ['./www/build/main.js']
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js'
},
module: {
rules: [
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'chunk'
})
]
}
After i run the webpack script, there are 3 files generated (vendor.bundle, app.bundle, chunk.bundle). My questions are:
What is the usage chunk.bundle and why it is generated? I set the config in "entry" and output is depends on the [name] of entry
How can i run the script to all files under a folder? The current setting needs to input one by one.
If my file is too large, how can i split is into some smaller files?
Thanks.
1) The chunk.bundle.js is being generated by the plugin. It operates a little outside of the usual Webpack flow.
2) Not sure what you're getting at, here. You probably need to look at the minChunks setting, or chunks.
3) You can use multiple instances of the plugin. I've found that you have to use the chunks setting on every instance except for one to avoid getting an error. Basically that specifies on what entry files the plugin will operate. You can specify all your entry files in chunks, and then use a function with minChunks to filter out what you want to include in that file.

Webpack 2 with angular 2 and asp.net mvc cshtml as template

I've a project running with Angular 2 and webpack 2 but currently I load all my templates directly into the js file with no addional template loading from the server. That works great.
#Component({
selector: 'logmonitor',
styleUrls: [ './logmonitor.component.less' ],
templateUrl: './logmonitor.component.html'
}) ...
but I need to load only some Templates from a cshtml view and the views should only get loaded with an extra server request when I open these views.
I've created a simple cshtml view in my views folder an I can directly "show" it when typing the right controller/action into the url. That "works"
but I've tried to set this to get the Template loaded
#Component({
selector: 'testView',
templateUrl: 'Logviewer/TestLogview',
}) ...
but webpack will not compile the view it gives a error
Module not found: Error: Can't resolve './Logviewer/TestLogview' in 'C:\SourceControl\WebLogViewer\App\Views\LogViewer'
thats right the file is daved in
C:\SourceControl\WebLogViewer\Views\LogViewer
but I don't want that webpack tries to resolve this url, angular itself need to call this url when the view gets loaded. I've thought webpack will not try to load the cshtml file when I don't write the "./" in front of the file name, but thats not working. Is there a solution how I can prevent webpack from parsing all templateUrl ?
thats my current Loader for html files, but this should not parse the string because there is not .html at the end :-/
{
test: /\.html$/,
use: ['raw-loader'],
exclude: [helpers.root('App/index.html')]
},
You can find a working example in this repo.
https://github.com/timdows/webpages/tree/master/Angular2RazorViews
The key is lazy loading and
angular2-load-children-loader
in loading the ts template dependencies

Resources