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

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.

Related

How to use es6 classes in *.cshtml

Added config files to the project (packege.json &webpack.config.json), added babel. At the moment it turns out like this: There is a directory / Scripts / build &Scripts / es6 (/main.js). When the npm run build command is run, everything builds ok (from themain.js file as indicated in the entry section of thewebpack.config.json file), the bundle.js file is created in the/ Scripts / build directory. In the above, there are no problems and everything is as it should. Now I want to use the js classes (their methods and properties) in the views (* .cshtml). How do i do this? Or need a different approach? If I write js code inmain.js, then I build it, then the code fulfills. But how do I make a function and run it (for example, by clicking a button)?
packege.json:
{
"name": "SensorDashboard",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --progress --mode='development' -p"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.2",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
}
}
webpack.config.js
const path = require('path');
module.exports = {
entry: ['./Scripts/es6/main.js'],
output: {
path: path.resolve(__dirname, './Scripts/build'),
filename: 'bundle.js'
},
// IMPORTANT NOTE: If you are using Webpack 2 or above, replace "loaders" with "rules"
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}]
}
}
main.js:
import { Map, MyClass } from './Map';
(function () {
window.test_func = function () {
let cl = new MyClass();
cl.send("asd qweqwe");
};
})();
MyClass:
export class MyClass {
send(message) {
console.log(message);
}
}
then i runing command: npm run build, and a file was created (/Script/build/bundle.js)
then i try to use in *.cshtml:
#{Layout = null;}
...
<script src="~/Scripts/build/bundle.js"></script>
...
<div>....</div>
<script type="text/javascript">
$(document).ready(function () {
test_func(); //this work
let m = new MyClass(); //this don`t work (MyClass is not defined)
m.send("asd");
});
</script>
I think should be as simple as loading the script in your .cshtml file with your standard script tag at the bottom of the file which would look something like this:
#section Scripts {
<script src="#Url.Content("~/Scripts/build/main.js")"></script>
}
(possibly without the #Url.Content though I'm not 100% sure offhand)
You could then call a function by doing something like the following example, there are a few ways and probably depends on what your class looks like in your main.js:
#section Scripts {
<script src="#Url.Content("~/Scripts/build/main.js")"></script>
document.getElementById("myButton").onclick = function(){
let someClass = new Class();
someClass.DoSomething();
}
}
Let me know if I've misunderstood the question.
Edit:
Okay, sorry I did misunderstand.
Have a look at this link and see if it helps you? It looks like exactly what you need.
It has instructions on how to configure webpack to allow calling externally.
Looks as simple as adding these two lines to your output:
libraryTarget: 'var',
library: 'EntryPoint'
Where EntryPoint is the Name you want for the module .
So:
output: {
path: path.resolve(__dirname, 'dist/js'),
filename: 'app.bundle.js',
libraryTarget: 'var',
library: 'MyModule'
},
And that should allow you to just call
EntryPoint.send("asd qweqwe");

Typescript equivalent of inline JavaScript

This may be self-evident but I'm not finding any example that informs what I'm trying to do (maybe I'm just doing it wrong). I'm adding Vue to an existing ASP.NET Core MVC application and adding the JavaScript statements directly to the page works but when I try to migrate to a TypeScript file nothing happens.
The JavaScript is:
new Vue({
el: "#productPage",
data: {
isLoading: true
},
methods: {
},
mounted () {
console.log("mounted()");
this.isLoading = false;
}
});
This works as expected. Migrating the code to a TypeScript file productPage.ts:
import Vue from 'vue';
new Vue({
el: "#productPage",
data: {
isLoading: true
},
methods: {
},
mounted () {
console.log("mounted()");
this.isLoading = false;
}
});
Which generates:
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "vue"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var vue_1 = require("vue");
var HonestyBox;
(function (HonestyBox) {
new vue_1.default({
el: "#productPage",
data: {
isLoading: true
},
methods: {},
mounted: function () {
console.log("Mounted !!!!");
this.isLoading = false;
}
});
})(HonestyBox || (HonestyBox = {}));
});
//# sourceMappingURL=productPage.js.map
And including the generated javascript file productPage.js:
<script src="~/js/productPage.js"></script>
This does nothing. Stepping through the debugger neither of the conditions in function(factory) are satisfied. The console tells me You are running Vue in development mode. but the included JavaScript fails to run. The tsconfig.json used to generate the JavaScript file:
{
"compileOnSave": true,
"compilerOptions": {
"module": "umd",
"moduleResolution": "node",
"noImplicitAny": false,
"noEmitOnError": true,
"removeComments": true,
"sourceMap": true,
"target": "es5",
"outDir": "wwwroot/js"
},
"include": [
"Typescript/**/*"
],
"exclude": [
"node_modules",
"wwwroot"
]
}
Using "module": "commonjs" results in ReferenceError: exports is not defined. I was hoping to avoid having to use Browserify or Webpack.
If I understand you correctly you add Vue in a separate script tag before your productPage.js.
This means that you can't import Vue in your TypeScript file, but you need to declare Vue so the module just assumes that Vue has been loaded already (outside of your TS module).
declare const Vue; // this replaces your Vue import statement
If you want to add a bundler later on, you need to remove your script tag which loads Vue and only go the modular approach:
Vue needs to be imported with an import statement so the bundler knows that he has to include all of Vue.
You will then have one single JS file (or if your bundler splits it: multiple JS files).

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

webpackMissingModule application.js on rails with angular app

I am following the steps like given by the author.
Following is the
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"
}
}
I am trying to change the default font to a different font by requiring the bootstrap.
My application.js looks like this
require("bootstrap/dist/css/bootstrap.css");
console.log("Hello world!");
And then I restarted the server. I see the text content are in same font-family as before nothing has changed when it should be actually a different font. And the console is giving the error as follows.
console
Uncaught Error: Cannot find module "bootstrap/dist/css/bootstrap.css"
at webpackMissingModule
webpack.config.js
// Example webpack configuration with asset fingerprinting in production.
'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;
I am not able to figure out if this is npm installing issue or something else. How can I fix this.
It seems your using older version of webpack, which I infer after seeing the resolve.root property. From webpack 1 docs
The directory (absolute path) that contains your modules. May also be an array of directories. This setting should be used to add individual directories to the search path.
So when your bootstrap.css files is being resolved instead of searching node_modules, it searches in your
resolve: { root: path.join(__dirname, '..', 'webpack')}

Angular2 quickstart main.js is searched to wrong path

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"

Resources