Angular2 quickstart main.js is searched to wrong path - asp.net-mvc

main.js is not loaded from http://localhost:6541/app/main.js , is searched to http://localhost:6541/Home/app/main.js and I receive 404.
So I have systemjs.config.js:
(function (global) {
var map = {
'app': 'app',
'#angular': 'lib/#angular',
'rxjs': 'lib/rxjs'
};
var packages = {
'app': { main: './main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js'}
};
var ngPackegeNames = [
'common',
'compiler',
'core',
'http',
'platform-browser',
'platform-browser-dynamic',
'router',
'router-deprecated',
'upgrade'
];
ngPackegeNames.forEach(function (pkgName) {
packages['#angular/' + pkgName] = {
main: pkgName + '.umd.js',
defaultExtension: 'js'
};
});
var config = {
map: map,
packages: packages
};
System.config(config);
})(this);
tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es6", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"rootDir": "app",
"outDir": "wwwroot/app"
},
"compileOnSave": true,
"exclude": ["node_modules","wwwroot/lib"]
}
in the layout I have:
<script src="~/lib/core-js/client/shim.min.js"></script>
<script src="~/lib/zone.js/dist/zone.js"></script>
<script src="~/lib/reflect-metadata/Reflect.js"></script>
<script src="~/lib/systemjs/dist/system.src.js"></script>
<script src="~/js/systemjs.config.js"></script>
<script>
System.import('app').catch(function (err) { console.error(err); });
</script>
in renderBody html file:
<my-app> Loading AppComponent content here ...</my-app>
nothing from Angular 2 Quickstart 404 GET /app/main.js does not worked.

I believe that the issue you are experiencing is a result of the MVC framework routing. Since the .cshtml file you are using lives in the Home Controller the routing starts at the base of the home controller (http://localhost:6541/Home).
You need to update the systemjs.config.js to backup to the base of the wwwroot folder using the .. character like so:
(function (global) {
var map = {
'app': '../app',
'#angular': '../lib/#angular',
'rxjs': '../lib/rxjs'
};
var packages = {
'app': { main: './main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js'}
};
var ngPackegeNames = [
'common',
'compiler',
'core',
'http',
'platform-browser',
'platform-browser-dynamic',
'router',
'router-deprecated',
'upgrade'
];
ngPackegeNames.forEach(function (pkgName) {
packages['#angular/' + pkgName] = {
main: pkgName + '.umd.js',
defaultExtension: 'js'
};
});
var config = {
map: map,
packages: packages
};
System.config(config);
})(this);
As an alternative, since angular is a SPA and you won't be doing much MVC routing it might make sense to have the TypeScript compile to the Home folder under the wwwroot folder. This will allow you to not have to make any changes to your systemjs.config.js file and the references to your app should work correctly. To do this modify your tsconfig.json like so:
"outDir": "wwwroot/Home/app"

Related

Webpacker, babel, uglifyjs-webpack-plugin - not transforming arrow functions, but only in Vue files

Running webpacker 3.5.5 (both the gem and package). This is mostly working, but in IE11 the app is broken because arrow functions do not appear to be transformed. However, inspecting the minified code it seems like the only place arrow functions aren't transformed are inside my vue components.
I think this is because my babel class properties plugin is not applying to my Vue loader somehow, but I haven't been able to come up with a solution.
Here's my .babelrc
{
"presets": [
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"> 1%",
"IE 11"
],
"uglify": true
},
"useBuiltIns": true
}
]
],
"plugins": [
"syntax-dynamic-import",
"transform-object-rest-spread",
[
"transform-class-properties",
{
"spec": true
}
]
],
"env": {
"test": {
"presets": ["es2015"]
}
}
}
And here's the entirety of my environment.js file that modifies the webpack environment that webpacker ships with (vue loader is at the bottom).
const { environment } = require('#rails/webpacker');
environment.loaders.append('expose', {
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: 'jQuery'
}]
});
const webpack = require('webpack');
// append some global plugins
environment.plugins.append('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
axios: 'axios',
moment: 'moment-timezone',
_: 'lodash'
}));
// Necesary configuration for vue-loader v15
const VueLoaderPlugin = require('vue-loader/lib/plugin');
environment.plugins.append(
'VueLoaderPlugin',
new VueLoaderPlugin()
);
environment.loaders.append('vue', {
test: /\.vue$/,
loader: 'vue-loader'
});
module.exports = environment;
Edit for more info: Here is the entry point to my pack called 'wrestling'
import 'babel-polyfill';
import 'wrestling';
Then in wrestling.js...
import './styles/wrestling'
import Rails from 'rails-ujs'
Rails.start();
import wrestlingSetup from './wrestlingSetup'
wrestlingSetup();
WrestlingSetup contains the actual references to the vue files. I've cut down the file to show what a single vue import looks like within the file. All the rest are essentially the same.
import Vue from 'vue/dist/vue.esm'
// Redacted a bunch of imports, but they all look like this oen
import WrestlerCreate from './vue/wrestler_create.vue'
export default function() {
document.addEventListener('DOMContentLoaded', () => {
axiosSetup();
const app = new Vue({
el: '#app',
components: {
// Other vue components here that I've removed for simplicity
WrestlerCreate,
}
})
});
}
Here's an actual example of the Vue component
<template>
<div role="form">
<!-- other form elements -->
</div>
</template>
<script>
export default {
name: 'wrestler-create',
props: [
],
// This does not get transformed by babel
data() {
return {
loading: false,
error: false,
errorMessage: "Error, please try again later or contact support.",
first_name: '',
last_name: '',
weight_class: '',
academic_class: ''
}
},
methods: {
// removed for simplicity
}
}
</script>
For clarify sake:
Please use function() for data. I find function() gives me less trouble than arrow functions.
export default {
data: function() {
return {
message: "Hello something!",
secondMessage: "Hello world!"
};
}
}
If you really wish to use arrow function, you can write:
export default {
data: () => {
return {
message: "Hello something!",
secondMessage: "Hello world!"
};
}
}

Not able to access right node_modules path on webpack-rails

I am trying for the first time to work with angularjs with rails as the back end. I am using webpack-rails gem for the webpack configuration for managing css and other style sheets.
First I made a sample angular + rails app to display a simple text "Hello world". By default the font was in times new roman. Then I added bootstrap to the package.json file as follows.
package.json
{
"name": "shine",
"version": "0.0.1",
"license": "MIT",
"dependencies": {
"stats-webpack-plugin": "^0.4.3",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2",
"css-loader": "^0.23.1",
"file-loader": "^0.9.0",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"bootstrap": "3.3.7"
}
}
Then I ran npm install which generated a folder named node_modules
with all the packages mentioned in the package.json in Project/node_modules path.
And webpack configuration to access access these package files is given in the
webpack.config.js
'use strict';
var path = require('path');
var webpack = require('webpack');
var StatsPlugin = require('stats-webpack-plugin');
// must match config.webpack.dev_server.port
var devServerPort = 3808;
// set NODE_ENV=production on the environment to add asset fingerprints
var production = process.env.NODE_ENV === 'production';
var config = {
entry: {
// Sources are expected to live in $app_root/webpack
'application': './webpack/application.js'
},
output: {
// Build assets directly in to public/webpack/, let webpack know
// that all webpacked assets start with webpack/
// must match config.webpack.output_dir
path: path.join(__dirname, '..', 'public', 'webpack'),
publicPath: '/webpack/',
filename: production ? '[name]-[chunkhash].js' : '[name].js'
},
resolve: {
root: path.join(__dirname, '..', 'webpack')
},
plugins: [
// must match config.webpack.manifest_filename
new StatsPlugin('manifest.json', {
// We only need assetsByChunkName
chunkModules: false,
source: false,
chunks: false,
modules: false,
assets: true
})]
};
if (production) {
config.plugins.push(
new webpack.NoErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({
compressor: { warnings: false },
sourceMap: false
}),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify('production') }
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin()
);
} else {
config.devServer = {
port: devServerPort,
headers: { 'Access-Control-Allow-Origin': '*' }
};
config.output.publicPath = '//localhost:' + devServerPort + '/webpack/';
// Source maps
config.devtool = 'cheap-module-eval-source-map';
}
module.exports = config;
And in my webpack/application.js I am calling that bootstrap package as follows.
require("bootstrap/dist/css/bootstrap.css");
console.log("Hello world!");
Now when I restart the server and reload the page I don't see any change in the font instead in the console I am getting.
Uncaught Error: Cannot find module "bootstrap/dist/css/bootstrap.css"
at webpackMissingModule
What am I doing wrong here ?
perhaps...
require('boostrap');
if that doesn't work, check to see if the file bootstrap/dist/css/bootstrap.css exists

ng-bootstrap AoT build failure with Unexpected Token and missing loader

I am trying to use ng-bootstrap library in my project. Runs fine with webpackdevserver and jit build but aot build throw errors similar to following
Module parse failed: E:\SVNCode\Learning\spa\aot\node_modules\#ng-
bootstrap\ng-bootstrap\alert\alert.ngfactory.ts Unexpected token (13:21)
You may need an appropriate loader to handle this file type.
I have searched for the issue but the only reference related to ng-bootstrap was ticket no. #1381 on github, which was closed without any further details. So, I believe that I may be missing something very small. Here are relevant details
Node : 8.1.3
Angular & Compiler-cli: 4.2.4
Webpack : 2.6.1
typescript : 2.3.4
ng-bootstrap : 1.0.0-alpha.26
bootstrap : 4.0.0-alpha.6 (using CDN but tried after install also with
same result)
webpack.prod.js
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let webpack = require('webpack');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CompressionPlugin = require("compression-webpack-plugin");
let CopyWebpackPlugin = require('copy-webpack-plugin');
let path = require('path');
let rootDir = path.resolve(__dirname, '..');
module.exports = {
entry: {
'polyfills': './spa/polyfills.ts',
'vendor': './spa/vendor-aot.ts',
'app': './spa/main-aot.ts' // AoT compilation
},
output: {
path: path.join(rootDir,'wwwroot'),
filename: 'js/[name]-[hash:6].bundle.js',
chunkFilename: 'js/[id]-[hash:6].chunk.js',
publicPath: '/'
},
resolve: {
extensions: ['.ts', '.js', '.json', '.css', '.html']
},
module: {
rules: [
{
test: /\.ts$/,
use: [
'babel-loader?presets[]=es2015',
'awesome-typescript-loader?configFileName=tsconfig-aot.json',
'angular-router-loader?aot=true&genDir=spa/aot/'
],
exclude: /node_modules/
},
{
test: /\.css$/,
loaders: ['to-string-loader', 'css-loader']
},
{
test: /\.html$/,
use: 'html-loader'
}
],
exprContextCritical: false
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
beautify: false,
compress: {
warnings: false
},
output: {
comments: false
},
sourceMap: false,
mangle: {keep_fnames: true}
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
new ExtractTextPlugin("[name].css"),
new HtmlWebpackPlugin({
template: './spa/index.html'
}),
new CopyWebpackPlugin([
{ from: path.join(rootDir,'spa','assets'), to: 'assets'}
]),
new webpack.NoEmitOnErrorsPlugin()
]
};
tsconfig-aot.js
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"lib": ["es2015","dom"],
"typeRoots": ["node_modules/#types"],
"types":["node", "core-js"]
},
"files": [
"spa/app/app.module.ts",
"spa/main-aot.ts"
],
"exclude": ["node_modules"],
"angularCompilerOptions": {
"genDir": "spa/aot",
"skipMetadataEmit": true
},
"awesomeTypescriptLoaderOptions":{
"useWebpackText": true,
"useCache": true
}
}
vendor-aot.ts
import '#angular/platform-browser';
import '#angular/core';
import '#angular/common';
import '#angular/http';
import '#angular/forms';
import '#angular/router';
import '#angular/platform-browser/animations';
import 'rxjs';
//can import others e.g. bootstrap, jquery etc
//can import js, ts, css, sass etc..
import '#ng-bootstrap/ng-bootstrap';
Thanks & Regards
After searching the internet high and low, going through several stackoverflow posts and github project configurations/samples, I finally managed to fix it (duct tape way).
All I had to do to fix the issue was remove the exclusion of node_modules folder in webpack config file.
Now, WHY exclusion of node_modules works for angular and rxjs packages but not for ng-bootstrap, is still beyond me.
Exclusion works when building for jit but for aot to succeed node_modules HAS TO BE INCLUDED in ts loader chain. Now the build time for aot has increased multifold, but at least it works.

use jquery-ui with webpack having a particular file structure

I would like you to help/suggest the best way to use datepicker from jquery-ui having the following file structure:
-single_pages
-admin
-admin.js
-webpack.config.js
-common
-DatesFilter
-DatesFilter.js
-node_modules
-package.json
I already installed jquery-ui
My webpack.config.js file is:
var path = require('path');
var webpack = require("webpack");
module.exports = {
resolve: {
alias: {
'jquery': require.resolve('jquery'),
},
root: [
path.resolve(__dirname, './../admin'),
path.resolve(__dirname, './../common')
],
extensions: ['', '.js'],
fallback: path.resolve(__dirname, './../node_modules')
},
resolveLoader: {
fallback: path.resolve(__dirname, './../node_modules')
},
entry: './index.js',
output: {
filename: 'bundle.js',
publicPath: "/"
},
externals: {
// require("jquery") is external and available
// on the global var jQuery
"jquery": "jQuery"
},
plugins: [
new webpack.ProvidePlugin({
"$":"jquery",
"jQuery":"jquery",
"window.jQuery":"jquery"
})
],
module: {
loaders: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, './')
],
loader: "babel-loader"
},
{
test: /\.js$/,
include: path.resolve(__dirname, './../common'),
babelrc: false,
loader: require.resolve('babel-loader'),
query: { // load the same presets as in the .babelrc file, but in a way that resolves in the parent directory
presets: [require.resolve('babel-preset-es2015'), require.resolve('babel-preset-react'),
require.resolve('babel-preset-stage-0')]
}
}
]
}
};
I'm using React.js.
I import DatesFilter.js inside admin.js. I get to see the component. The problem comes when I want to use the datepicker.
DatesFilter.js uses datepicker from jquery-ui
I'm using: import { datepicker } from 'jquery-ui' inside DatesFilter.js but it keeps saying TypeError: $(...).datepicker is not a function
What can I do?
Thank you
Try importing just the module, see this link jquery-ui-and-webpack-how-to-manage-it-into-module
in your case you would import "jquery-ui/ui/widgets/datepicker"

Not able to load boot.js when rendered through AspNet-Core-MVC views

Not able to load boot.js when rendered through AspNet-Core-MVC views
I tried creating a ApsNet core + Angular2 RC4 application. Following are the steps which I have done to build the app
1. Created/updated the Package.json, systemjs.config.js, typings.json and tsconfig.json from the angular (RC4) quickstart tutorials with small changes to it as per my need
2. Placed all the angular2 components under scripts folder and also placed tsconfig.json under the same. But specified the outDir property to move all the transpiled .js files to wwwroot/appScripts/ folder.
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"noEmitOnError": true,
"noImplicitAny": true,
"outDir": "../wwwroot/appScripts/",
"removeComments": false,
"sourceMap": true,
"suppressImplicitAnyIndexErrors": true,
"moduleResolution": "node",
"target": "es6"
},
"compileOnSave": true,
"exclude": [
"node_modules",
"wwwroot"
]
}
modified the systemjs.config.js as below to load the boot.js file for 'app' mapping
(function (global) {
// map tells the System loader where to look for things
var map = {
'app': 'app', // 'dist',
'#angular': 'lib/#angular',
'rxjs': 'lib/rxjs'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'boot.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' }
};
var ngPackageNames = [
'common',
'compiler',
'core',
'http',
'platform-browser',
'platform-browser-dynamic',
'router',
'router-deprecated',
'upgrade',
];
// Add package entries for angular packages
ngPackageNames.forEach(function (pkgName) {
packages['#angular/' + pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' };
}) ;
var config = {
map: map,
packages: packages
}
System.config(config);
})(this);
When the application loads, initally it lands on the login page and on authentication it redirects to the "Views/Home/index.cshtml" view which is rendered by the Login controller.
This "Views/Home/index.cshtml" view is having/under the layout set to "./shared/layout.cshtml" file
My "Views/Home/index.cshtml" is as below
#{
ViewData["Title"] = "Home Page";
Layout = "_Layout";
}
<!-- IE required polyfills, in this exact order -->
<script src="~/lib/core-js/client/shim.min.js"></script>
<script src="~/lib/zone.js/dist/zone.js"></script>
<script src="~/lib/reflect-metadata/Reflect.js"></script>
<script src="~/lib/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
System.import('app').catch(function (err) { console.error(err); });
</script>
Earlier when i developed it from the scratch it was with the angular2 - beta 17 version, but now I have migrated to Angular2 RC4.
The problem now I am facing is the application is not able to load the boot.js file and I am getting the following error in the browser console
menu.js:103 Uncaught TypeError: $(...).tooltip is not a function
http://localhost:55413/Home/app/boot.js Failed to load resource: the server responded with a status of 404 (Not Found)
Index:54 Error: Error: XHR error (404 Not Found) loading http://localhost:55413/Home/app/boot.js
at XMLHttpRequest.wrapFn [as _onreadystatechange] (http://localhost:55413/lib/zone.js/dist/zone.js:769:30)
at ZoneDelegate.invokeTask (http://localhost:55413/lib/zone.js/dist/zone.js:356:38)
at Zone.runTask (http://localhost:55413/lib/zone.js/dist/zone.js:256:48)
at XMLHttpRequest.ZoneTask.invoke (http://localhost:55413/lib/zone.js/dist/zone.js:423:34)
Error loading http://localhost:55413/Home/app/boot.js(anonymous function) # Index:54
http://localhost:55413/app/boot.js Failed to load resource: the server responded with a status of 404 (Not Found)
Index:84 Error: Error: XHR error (404 Not Found) loading http://localhost:55413/app/boot.js
at XMLHttpRequest.wrapFn [as _onreadystatechange] (http://localhost:55413/lib/zone.js/dist/zone.js:769:30)
at ZoneDelegate.invokeTask (http://localhost:55413/lib/zone.js/dist/zone.js:356:38)
at Zone.runTask (http://localhost:55413/lib/zone.js/dist/zone.js:256:48)
at XMLHttpRequest.ZoneTask.invoke (http://localhost:55413/lib/zone.js/dist/zone.js:423:34)
Error loading http://localhost:55413/app/boot.js
Why the application is not able to identify/load the boot.js file, I am pointing to wrong path to load it? what is the change I need to do?
You are outputting your scripts to "appScripts/ or "scripts/" (your screenshots show two different "script" directories) but then you are trying to load your boot.js from the /Home/app directory. Change your system.config.ts:
var packages = {
'app': { main: 'scripts/boot.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' }
};
Or change your tsconfig outDir property.

Resources