Widget from Angular 2 app webpack - javascript

If it is unclear than let's try this again.
In my research I learned that some call it a micro-loader, which is what I am trying to achieve. In the webpack configuration I have this in the plugin section
new HtmlWebpackPlugin({
template: 'src/index.html',
title: METADATA.title,
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'head'
}),
which turns an html file without any script tags (or even placeholders for them) during compilation in something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My angular widget</title>
<meta name="description" content="My angular widget">
<!-- base url -->
<base href="/">
<link href="main.23ca1423b5f74b9e7d3a76e9eed69f71.css" rel="stylesheet"><script type="text/javascript" src="polyfills.60dbe827b1b8353af66f.bundle.js" defer></script><script type="text/javascript" src="vendor.0f040ba30b8e909c6a82.bundle.js" defer></script><script type="text/javascript" src="main.d6e9175158901f87b307.bundle.js" defer></script></head>
<body>
<app class="skin-green gbp">
Loading...
</app>
</body>
</html>
It magically adds those 4 files (1 css, 3 js) into the head section.
Now what I want is something like this (the angular-widget.js file)
function loadCss(url) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}
loadCss('https://my-domain.com/app/main.1928b5b43a58428e7798d12176de68e3.css');
require(['https://my-domain.com/app/polyfills.60dbe827b1b8353af66f.bundle.js'], function() {
require(['https://my-domain.com/app/vendor.623bbcbf99de3526eab8.bundle.js'], function() {
require(['https://my-domain.com/app/main.d4f6aea1525a044b41da.bundle.js'], function() {
});
});
});
Which is a file I came up which does what I want it to do, but takes manual work everytime and utilizes require.js for now (but can be anything, I don't really care), which is the only point of entry and gets automatically generated during the compilation so I don't have to manually change the hashes everytime something changes and gets redeployed.
-- Old Post starts here
I have an angular 2 project using webpack for compiling. But I do not want the entry point to be the index.html, because the app is to be embeded into another webpage, which I do not have full control over.
I am trying to find a way to output something similar to the index.html but inside a .js file which I than can include on the webpage.
www.some-domain.com/webpage
[...]
<script type="text/javascript" src="https://my-domain.com/angular-widget.js"></script>
<app>
Loading...
</app>
[...]
Is there a way to generate that angular-widget.js during the webpack process? I tried to hijack the HtmlWebpackPlugin, but that expects to output HTML. I am fairly new to the whole webpack process, but my approach right now would be some template where I just can output the different files which are produced by webpack, for example using require.js. But maybe the whole thing is even possible only via webpack?

Related

Newby: index.js file doesn't work in index.html file

I'm new in Javascript world, currently I'm trying to implement a GUI using electron js framework.
Trying to reproduce the code from a tutorial, I got stuck on a code which seems not to work on my PC, basically even if I click on a button, the console is not logging anything (when it should have!!); the aim of the code is to refer to a button defined in an index.html file from a index.js containing the script and log a sentence when the button is clicked, but it seems like the script in the html file cannot access the .js file at all. Here I'm reporting the code from index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>my-app</title>
<link rel = "stylesheet" href="styles.css">
</head>
<body>
<button id = "button1" > START </button>
<script>
require('./index.js');
</script>
</body>
</html>
Here the code belonging to index.js file:
const electron = require("electron");
const button1 = document.getElementById("button1");
button1.addEventListener("click", startApp);
function startApp(){
console.log("Button clicked!");
};
Note:
I've tried to debug this code based on my very little knowledge of Javascript and electron:
I used document.getElementById("button1"); in index.html and it does work (the variable obtained was used to change button text color), but the same is not working when reported in the index.js file;
I tried console.log("In index.js"); in index.js but still it is not working!
From these results I thought the problem may be the .html and .js file communication; they are in the same folder. One more thing: I downloaded the tutorial code from GitHub and the problem is still present with the same actions at points 1 and 2.
Edit: I've omitted that I'm linking index.html window and displaying it in the main.js file, in fact the windows does show up, but the the click on the button doesn't produce any action.
Seemed to be a problem with the require module not working in .html file.
Solved by replacing it with <script src="index.js"></script>.
It appears that you shoud be using electron to load the index.html via BrowserWindowonce it is ready. app and BrowserWindow are from the electron module.
`const { app, BrowserWindow } = require('electron')`
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})
From the quick start
In Electron, browser windows can only be created after the app module's ready event is fired. You can wait for this event by using the app.whenReady() API. Call createWindow() after whenReady() resolves its Promise.
For futher info see https://www.electronjs.org/docs/tutorial/quick-start
Hope this proves useful.

Blazor WebAssembly Environment Variables

I'm currently working on a .NET Standard 2.1 Blazor WebAssembly application.
I try to include or exclude Stylesheets according to an environment variable.
In .NET Core there are usually Environment Tag Helpers like in the following example:
<environment include="Development">
<link rel="stylesheet" href="css/style.css" type="text/css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="css/style.min.css" type="text/css" />
</environment>
This works perfectly fine in a Blazor Server application, but doesn't in Blazor WASm, as this is client-side code.
Thus I try to find a good solution to include/exclude Style sheets according to the Environment variable in Blazor WebAssembly.
My current approach is to call a JavaScript helper method from my Blazor WASm Program.cs file with JSInterop and remove the Stylesheets according to the environment variable:
await jsInterop.InvokeVoidAsync("helpers.setup", "Development");
My JavaScript on the client looks like this:
window.helpers = {
setup: (environment) => {
if (environment === "Development") {
// remove production styles
}
if (environment !== "Development") {
// remove development styles
}
}
};
The problem with this solution is, I want to put my styles into my header file and group them into a <section> element or something similar - which doesn't work in valid HTML5.
How do you handle your Development/Production environment in Blazor WebAssembly?
How can you exclude or include specific CSS files according to the set environment variable in the project settings (launchsettings.json)?
Disclaimer:
This is just something I tried that seems to work. I could not find any documentation supporting doing it this way, nor anything saying not to do it this way. if there is any official documentation please let me know.
The documentation state:
When running an app locally, the environment defaults to Development.
When the app is published, the environment defaults to Production.
Further down it does mention how to set the environment via the web.config that gets generated when publishing the file to IIS.
There are also references to Use multiple environments in ASP.NET Core. and Host and deploy ASP.NET Core Blazor WebAssembly
However this is what I did.
Looking at the Program.cs file that was generated by the new web assembly project template, the builder is created by WebAssemblyHostBuilder.CreateDefault(args); This must mean that all the default services must already be registered in the services container.
This would include the IWebAssemblyHostEnvironment configuration service.
The next line down builder.RootComponents.Add<App>("app"); adds the App <app></app> root component that is used in the index.html file.
So, Why not try to create a Head <head></head> component and see what happens.
I created a Head razor component and named it Head.razor containing all the html that would usually live between the <head></head> tags.
#using Microsoft.AspNetCore.Components.WebAssembly.Hosting
#inject IWebAssemblyHostEnvironment hostEnv
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
#*Check the environment value*#
#if (hostEnv.IsDevelopment())
{
<title>BlazorWasmApp - In Debug</title>
<link href="css/debug.css" rel="stylesheet" />
}
else
{
<title>BlazorWasmApp - Not Debug</title>
<link href="css/live.css" rel="stylesheet" />
}
#code {}
Because it is a component you can inject the IWebAssemblyHostEnvironment and check the .IsDevelopment(),.IsProduction() etc.. extension method values.
I left the original <head> tag as is in the index.html file as the content of the <head>...gets overwritten...</head> seems to be completely overwritten.
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>BlazorWasmApp</title>
<base href="/" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
...
...
Also leaving the <head>tag with the reference to the cs/app.css file does not change the way it looks when the app is Loading....
I registered the Head class to the builder.RootComponents collection in the Program class.
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
//Add the Head to root components
builder.RootComponents.Add<Head>("head");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
}
I added 2 css files to the wwwroot/css folder debug.css and live.css each containing a simple body { background-color:*red or blue* } style.
In the launchSettings.json file, in the profiles section, set the IIS Express : environmentVariables : ASPNETCORE_ENVIRONMENT to "Development" and under the [YourAppName] : environmentVariables : ASPNETCORE_ENVIRONMENT to "Production".
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
},
"BlazorWasmApp": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
}
}
When launching the app with the IIS Express profile (Development) the background is red and when launching the app with [YourAppName] profile (Production) the background is blue.
When looking at the <head></head> tags using the developer tools the content of the head tag contains the css references according to the environment.
IIS Express:
BlazorWasmApp (my app profile):

vue-cli 3 pages config will serve javascript but does not fire it

I'm running into an issue when trying to use the pages config for vue-cli v3.
I have two pages setup, my index page and a test page:
pages: {
index: {
entry: "src/main.js",
template: "public/index.html",
filename: "index.html",
title: "Index Page",
chunks: ["chunk-vendors", "chunk-common", "index"]
},
"test-case-study": {
entry: "src/subpage/test-case-study.js",
template: "public/test-case-study.html",
filename: "test-case-study.html",
title: "Test case study",
chunks: ["chunk-vendors", "chunk-common", "test-case-study"]
}
}
I have my entry point files and templates in the (I'm assuming) correct spots:
And when I run npm run serve and navigate to the test page (http://localhost:8080/test-case-study.html) to check, the markup loads correct, the javascript file comes through successfully in the network tab, but I get the error
The resource http://localhost:8080/test-case-study.js was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate as value and it is preloaded intentionally.
The script tag is getting added to the head successfully:
And when I look in the source tab at the javascript it all looks correct and I can see the evaluate function call with my custom javascript, but nothing ever fires.
UPDATE
I ran an build and checked the output of the dist/test-case-study.html file and it looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<title>Test case study</title>
<link href=/js/chunk-vendors.96f8ab67.js rel=preload as=script>
<link href=/js/test-case-study.d382d007.js rel=preload as=script>
</head>
<body>
<h1>hi</h1>
<div id=app></div>
<script src=/js/chunk-vendors.96f8ab67.js></script>
<script src=/js/test-case-study.d382d007.js></script>
</body>
</html>
It's weird that the javascript is being pulled in twice, and I still don't get why it wouldn't fire. You'd think it would fire more than once vs not at all.
Is there something I'm missing from my config?

nopcommerce 3.80 ender-blocking JavaScript and CSS in above-the-fold content

I'm using the "async" property of Html.AppendScriptParts method in nopcommerce 3.80 like that Html.AppendScriptParts("~/Scripts/jquery-1.10.2.min.js",false,true);
The google PageSpeed Tools give it a high score which is i expected:
But it seems effect to the other functionalities of website (nivo slider, ajax filter which comes from Seven Spikes plugin,... )
I'm not using js and css bundling feature in nopcommerce.
Can you guys please tell me what is the best solution in my scenarior now ?
Any helps are very appriciated.
Thank you so much.
Here is my code of _Root.head.cshtml:
#using Nop.Core.Domain.Common;
#using Nop.Core.Domain.Seo
#using Nop.Core.Infrastructure;
#{
var displayMiniProfiler = EngineContext.Current.Resolve<Nop.Core.Domain.StoreInformationSettings>().DisplayMiniProfilerInPublicStore;
Html.AppendScriptParts("~/Scripts/public.ajaxcart.js");
Html.AppendScriptParts("~/Scripts/public.common.js");
Html.AppendScriptParts("~/Scripts/jquery-migrate-1.2.1.min.js");
Html.AppendScriptParts("~/Scripts/jquery-ui-1.10.3.custom.min.js");
Html.AppendScriptParts("~/Scripts/jquery.validate.unobtrusive.min.js");
Html.AppendScriptParts("~/Scripts/jquery.validate.min.js");
Html.AppendScriptParts("~/Scripts/jquery-1.10.2.min.js",false,true);
var commonSettings = EngineContext.Current.Resolve<CommonSettings>();
if (commonSettings.RenderXuaCompatible)
{
Html.AppendHeadCustomParts(string.Format("<meta http-equiv=\"X-UA-Compatible\" content=\"{0}\"/>", commonSettings.XuaCompatibleValue));
}
var seoSettings = EngineContext.Current.Resolve<SeoSettings>();
if (!string.IsNullOrEmpty(seoSettings.CustomHeadTags))
{
Html.AppendHeadCustomParts(seoSettings.CustomHeadTags);
}
}
<!DOCTYPE html>
<html#(this.ShouldUseRtlTheme() ? Html.Raw(" dir=\"rtl\"") : null) #Html.NopPageCssClasses()>
<head>
<title>#Html.NopTitle()</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<meta name="description" content="#(Html.NopMetaDescription())" />
<meta name="keywords" content="#(Html.NopMetaKeywords())" />
<meta name="generator" content="nopCommerce" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
#Html.NopHeadCustom()
#Html.Partial("Head")
#Html.Widget("head_html_tag")
#Html.NopCssFiles(this.Url, ResourceLocation.Head)
#Html.NopScripts(this.Url, ResourceLocation.Head)
#Html.NopCanonicalUrls()
#Html.Action("RssHeaderLink", "News")
#Html.Action("RssHeaderLink", "Blog")
#Html.Action("Favicon", "Common")
#if (displayMiniProfiler)
{
#StackExchange.Profiling.MiniProfiler.RenderIncludes()
}
</head>
<body>
#RenderBody()
#Html.NopCssFiles(this.Url, ResourceLocation.Foot)
#Html.NopScripts(this.Url, ResourceLocation.Foot)
</body>
</html>
First, it's not related to Seven Spikes plugins. This issue is because of async behavior. When you make jquery file to an async, it means application will not wait to load that file and going to load next js file. But other js file are depended on first main file, and that's way you're getting errors.
Let's understand it with current scenario, the default code is:
Html.AppendScriptParts("~/Scripts/public.ajaxcart.js");
Html.AppendScriptParts("~/Scripts/public.common.js");
Html.AppendScriptParts("~/Scripts/jquery-migrate-1.2.1.min.js");
Html.AppendScriptParts("~/Scripts/jquery-ui-1.10.3.custom.min.js");
Html.AppendScriptParts("~/Scripts/jquery.validate.unobtrusive.min.js");
Html.AppendScriptParts("~/Scripts/jquery.validate.min.js");
Html.AppendScriptParts("~/Scripts/jquery-1.10.2.min.js");
In this case the order of js files are:
Now load jquery min js file asynchronously.
Html.AppendScriptParts("~/Scripts/jquery-1.10.2.min.js", false, true);
And check console:
With this change you will get an error(s).
To resolve this issue, you have to load js min file in one particular order on basis of dependency.
Side Note: this issue is with default code too!! I've tested with nopCommerce 3.80 and 3.90

Javascript App Windows Universal - Script Issue

I created a Website using material design lite:
Scripts:
<script src="./mdl/material.min.js"></script>
<script src="Scripts/angular.min.js"></script>
.css files included in html:
<link rel="stylesheet" href="./mdl/material.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
It is looking like this:
After that I created a new uwp JavaScript Project and mainly just used C&P.
The result is:
Of Course I applied the right source paths for the scripts for uwp.
My Uwp Folder structure:
In my uwp the paths are this:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="js/mdl/material.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
And in the Body:
<script src="/js/mdl/material.min.js"></script>
<script src="/js/Scripts/angular.min.js"></script>
Seems like the problem is actually not with local styles or scripts but with the external one you are using for icons. UWP blocks including external scripts or css-files into pages executed in local context. I would also highlight that it is not recommended per design principles as all your interface-related icons should not depend on internet connection.
You should include that CSS-file for material design icons into your project (and I suppose font-files as well).
Or just hack the security of UWP and use this trick :
function loadExternalScriptAsync (scriptUrl)
{
return WinJS.xhr({ url: scriptUrl }).then(function(req) {
var scriptTxt = req.responseText;
try
{
var bb = new MSBlobBuilder();
bb.append(scriptTxt);
var data = bb.getBlob('text/javascript');
var sc = document.createElement('script');
sc.setAttribute('src', window.URL.createObjectURL(data));
document.head.appendChild(sc);
return true;
}
catch (e)
{
return false;
}
})
},
Which will download the script save it as a blob, and then will be allowed to reference it. Will definitely work for css, and have some limitation for JS since it won't work if the downloaded script try it self to load external script
I'm using WinJS.xhr...but any XmlHttprequest will works as well
Romain

Categories