Blazor WebAssembly Environment Variables - javascript

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):

Related

Gatsby & contentful site incorrect files path in public build

Trying to deploy Gatsby site with Contentful CMS. Everything works just fine in development mode - things get rough when I'm trying to build.
Gatsby build command deploys the site, all seems OK at first, but it throws errors preventing my content from loading.
Easier way to show it is just to check my github LIVE:
GIT LIVE
Short description: seems like path to files error - trying to GET files from direct path (local F:\ path for me -> my main github page for git LIVE (name.github.io/...))
I'm having the very same problem with raw Gatsby website built.
My (raw) gatsby main site goes like:
<!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, shrink-to-fit=no" />
<link rel="preload" href="/component---src-layouts-index-js-07253e04741551c85ebc.js" as="script" />
<link rel="preload" href="/component---src-pages-index-js-df93eb0c88a52638909b.js" as="script" />
<link rel="preload" href="/path---index-a0e39f21c11f6a62c5ab.js" as="script" />
<link rel="preload" href="/app-29169f9e7be0e183bc9a.js" as="script" />
<link rel="preload" href="/commons-fcbb8af1639fee4f6844.js" as="script" />
<title data-react-helmet="true">Gatsby Default Starter</title>
<meta data-react-helmet="true" name="description" content="Sample" />
<meta data-react-helmet="true" name="keywords" content="sample, something" />
<style id="gatsby-inlined-css">
</style>
</head>
<body>
<div id="___gatsby">
<div data-reactroot="" data-reactid="1" data-react-checksum="238678071">
<!-- react-empty: 2 -->
<div style="background:rebeccapurple;margin-bottom:1.45rem;" data-reactid="3">
<div style="margin:0 auto;max-width:960px;padding:1.45rem 1.0875rem;" data-reactid="4">
<h1 style="margin:0;" data-reactid="5"><a style="color:white;text-decoration:none;" href="/" data-reactid="6">Gatsby
Default Starter</a></h1>
</div>
</div>
<div style="margin:0 auto;max-width:960px;padding:0px 1.0875rem 1.45rem;padding-top:0;" data-reactid="7">
<div data-reactid="8">
<h1 data-reactid="9">Hi people</h1>
<p data-reactid="10">Welcome to your new Gatsby site.</p>
<p data-reactid="11">Now go build something great.</p>Go to page 2
</div>
</div>
</div>
</div>
<script id="webpack-manifest">
/*<![CDATA[*/
window.webpackManifest = {
"231608221292675": "app-29169f9e7be0e183bc9a.js",
"162898551421021": "component---src-pages-404-js-4503918ea3a16cfcdb75.js",
"35783957827783": "component---src-pages-index-js-df93eb0c88a52638909b.js",
"218538773642512": "component---src-pages-page-2-js-1d4f0f19c1c44398ab65.js",
"60335399758886": "path----cac63ff5c1b42581353c.js",
"254022195166212": "path---404-a0e39f21c11f6a62c5ab.js",
"142629428675168": "path---index-a0e39f21c11f6a62c5ab.js",
"135728916539164": "path---page-2-a0e39f21c11f6a62c5ab.js",
"178698757827068": "path---404-html-a0e39f21c11f6a62c5ab.js",
"114276838955818": "component---src-layouts-index-js-07253e04741551c85ebc.js"
} /*]]>*/
</script>
<script>
/*<![CDATA[*/
["/commons-fcbb8af1639fee4f6844.js", "/app-29169f9e7be0e183bc9a.js", "/path---index-a0e39f21c11f6a62c5ab.js",
"/component---src-pages-index-js-df93eb0c88a52638909b.js",
"/component---src-layouts-index-js-07253e04741551c85ebc.js"
].forEach(function (s) {
document.write('<script src="' + s + '" defer></' + 'script>')
}) /*]]>*/
</script>
</body>
</html>
Resolving path manually e.g replacing link href like this:
<link rel="preload" href="/component---src-layouts-index-js-07253e04741551c85ebc.js" as="script" />
into (just adding the dot)
<link rel="preload" href="./component---src-layouts-index-js-07253e04741551c85ebc.js" as="script" />
makes this particular error go away, throwing warning as below:
The resource file://(path here) 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.
and another error (pointed NOT at line from HTML HEAD anymore but at the last script (signed as CDATA)
<script>
/*<![CDATA[*/
["/commons-fcbb8af1639fee4f6844.js", "/app-29169f9e7be0e183bc9a.js", "/path---index-a0e39f21c11f6a62c5ab.js",
"/component---src-pages-index-js-df93eb0c88a52638909b.js",
"/component---src-layouts-index-js-07253e04741551c85ebc.js"
].forEach(function (s) {
document.write('<script src="' + s + '" defer></' + 'script>')
}) /*]]>*/
</script>
Going further - changing path here creates another "funny" thing.
When trying to load the page, it "flashes" site with styles and all (just for a split second) and then throws multiple errors like
A page wasn't found for "/F:/HTML/TEST-2/site/public/index.html
bundle loading error true
Loading the component for /404.html failed
bundle loading error true
Loading the JSON for /404.html failed
I'm aware that I shouldn't be doing this all fix-the-path-by-myself thing in working process, however I have no idea where the problem lies in.
Hope I made my problem clear :)
I did a deeper dive on the errors present on your site.
1- The first pair of errors I see is related to Font Awesome:
Subresource Integrity: The resource
'https://use.fontawesome.com/releases/v5.3.1/css/solid.css' has an
integrity attribute, but the resource requires the request to be CORS
enabled to check the integrity, and it is not. The resource has been
blocked because the integrity cannot be enforced.
Subresource Integrity: The resource
'https://use.fontawesome.com/releases/v5.3.1/css/fontawesome.css' has
an integrity attribute, but the resource requires the request to be
CORS enabled to check the integrity, and it is not. The resource has
been blocked because the integrity cannot be enforced.
These related to CORS for the integrity attribute on your Font Awesome includes (line 29 in your compressed codebase).
<link data-react-helmet="true" rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/solid.css" integrity="sha384-VGP9aw4WtGH/uPAOseYxZ+Vz/vaTb1ehm1bwx92Fm8dTrE+3boLfF1SpAtB1z7HW"/>
<link data-react-helmet="true" rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/fontawesome.css" integrity="sha384-1rquJLNOM3ijoueaaeS5m+McXPJCGdr5HcA03/VHXxcp2kX2sUrQDmFc3jR5i/C7"/>
Just delete the checksum hash, or you might want to check why these aren't valid. This is why the CSS is flashing ok; Chrome checks the hash, sees it's invalid and removes it from the DOM.
2- The second set of errors has a bunch of your JS files 404ing. The errors look like this in Chrome DevTools:
GET
https://emzawadzki.github.io/component---src-layouts-index-js-4386bcf88f311dc59346.js
net::ERR_ABORTED 404
If we isolate where the paths are coming from for these files, you can trace them to your webpack build's manifest (line 738):
<script id="webpack-manifest">
/*<![CDATA[*/
window.webpackManifest = {
"231608221292675": "app-cdbd5391462f32fb5915.js",
"162898551421021": "component---src-pages-404-js-f6662393a31fb18d5e07.js",
"35783957827783": "component---src-pages-index-js-6fe4a58b68048902490d.js",
"60335399758886": "path----557518bd178906f8d58a.js",
"254022195166212": "path---404-a0e39f21c11f6a62c5ab.js",
"142629428675168": "path---index-a0e39f21c11f6a62c5ab.js",
"178698757827068": "path---404-html-a0e39f21c11f6a62c5ab.js",
"114276838955818": "component---src-layouts-index-js-4386bcf88f311dc59346.js"
}
/*]]>*/
</script>
The error is in your webpack build. Gatsby hides most of the webpack building stuff behind the scenes, so the error is likely coming out of your gatsby-config.js file. If you can tweak that, I'm pretty sure that's where this second problem is coming from. Comment out everything you aren't using and double check your local error logs.

System.OutOfMemory Exception on loading Javascript libraries

In my application I have referenced JQWidget libraries and styles using Bundle options like below.
bundles.Add(new ScriptBundle("~/bundles/jqwidgets").Include(
"~/JQWidgets/jqx-all.js",
"~/JQWidgets/jqxcore.js",
"~/JQWidgets/jqxdata.js",
"~/JQWidgets/jqxgrid.js",
"~/JQWidgets/jqxgrid.selection.js",
"~/JQWidgets/jqxgrid.pager.js",
"~/JQWidgets/jqxlistbox.js",
"~/JQWidgets/jqxbuttons.js",
"~/JQWidgets/jqxscrollbar.js",
"~/JQWidgets/jqxdatatable.js",
"~/JQWidgets/jqxtreegrid.js",
"~/JQWidgets/jqxmenu.js",
"~/JQWidgets/jqxcalendar.js",
"~/JQWidgets/jqxgrid.sort.js",
"~/JQWidgets/jqxgrid.filter.js",
"~/JQWidgets/jqxdatetimeinput.js",
"~/JQWidgets/jqxdropdownlist.js",
"~/JQWidgets/jqxslider.js",
"~/JQWidgets/jqxeditor.js",
"~/JQWidgets/jqxinput.js",
"~/JQWidgets/jqxdraw.js",
"~/JQWidgets/jqxchart.core.js",
"~/JQWidgets/jqxchart.rangeselector.js",
"~/JQWidgets/jqxtree.js",
"~/JQWidgets/globalize.js",
"~/JQWidgets/jqxbulletchart.js",
"~/JQWidgets/jqxcheckbox.js",
"~/JQWidgets/jqxradiobutton.js",
"~/JQWidgets/jqxvalidator.js",
"~/JQWidgets/jqxpanel.js",
"~/JQWidgets/jqxpasswordinput.js",
"~/JQWidgets/jqxnumberinput.js",
"~/JQWidgets/jqxcombobox.js",
"~/JQWidgets/jqxgrid.edit.js",
"~/JQWidgets/jqxgrid.columnsresize.js",
"~/JQWidgets/jqxgrid.columnsreorder.js",
"~/JQWidgets/jqxdata.js",
"~/JQWidgets/jqxgrid.export.js",
"~/JQWidgets/jqxdata.export.js",
"~/JQWidgets/jqxgrid.grouping.js",
"~/JQWidgets/jqxgrid.aggregates.js",
"~/JQWidgets/jqxtabs.js",
"~/JQWidgets/jqxwindow.js"
));
bundles.Add(new StyleBundle("~/JQWidgets/Styles/css").Include(
"~/JQWidgets/Styles/jqx.base.css",
"~/JQWidgets/Styles/jqx.arctic.css",
"~/JQWidgets/Styles/jqx.black.css",
"~/JQWidgets/Styles/jqx.bootstrap.css",
"~/JQWidgets/Styles/jqx.classic.css",
"~/JQWidgets/Styles/jqx.darkblue.css",
"~/JQWidgets/Styles/jqx.energyblue.css",
"~/JQWidgets/Styles/jqx.fresh.css",
"~/JQWidgets/Styles/jqx.highcontrast.css",
"~/JQWidgets/Styles/jqx.metro.css",
"~/JQWidgets/Styles/jqx.metrodark.css",
"~/JQWidgets/Styles/jqx.office.css",
"~/JQWidgets/Styles/jqx.orange.css",
"~/JQWidgets/Styles/jqx.shinyblack.css",
"~/JQWidgets/Styles/jqx.summer.css",
"~/JQWidgets/Styles/jqx.web.css",
"~/JQWidgets/Styles/jqx.ui-darkness.css",
"~/JQWidgets/Styles/jqx.ui-lightness.css",
"~/JQWidgets/Styles/jqx.ui-le-frog.css",
"~/JQWidgets/Styles/jqx.ui-overcast.css",
"~/JQWidgets/Styles/jqx.ui-redmond.css",
"~/JQWidgets/Styles/jqx.ui-smoothness.css",
"~/JQWidgets/Styles/jqx.ui-start.css",
"~/JQWidgets/Styles/jqx.ui-sunny.css",
"~/JQWidgets/Styles/bootstrap.css",
"~/JQWidgets/Styles/site.css"
));
BundleTable.EnableOptimizations = true;
And in my _Layout.cshtml I have referenced them like this in head and body tags respectively.
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - Gulf Piping Company</title>
#Styles.Render("~/Content/css")
**#Styles.Render("~/jqwidgets/styles/css")**
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
**#Scripts.Render("~/bundles/jqwidgets")**
#Scripts.Render("~/bundles/ajax")
#RenderSection("scripts", required: false)
Now, since my application is in development stage, so I keep running the application, make changes and refresh the browser as required. After certain number of refreshes (cant tell how many), i get this error message.
I have to close browser, close Visual Studio and then re run Visual studio, load solution again and then run the appliction to overcome this error. Can any one tell me what is going on here?
Also, i have different views/pages in my application and some pages reference some of above JQWidget libraries and some don't (i.e. not all pages use all of these libraries), so is Bundling really the right way to use or there is a better way to reference libraries?

Widget from Angular 2 app webpack

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?

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

Building Dojo 1.7 for Mobile PhoneGap App

I am trying to build dojo 1.7 to use in my phonegap application. I am currently using dojo 1.6.1. I built my current dojo.js file by going to build.dojotoolkit.org and selecting everything under dojox.mobile as well as a dojo.store.JsonRest module. That works great.
My issue is trying to create a profile file to create a build similiar to the one I got from the dojo build website.
I downloaded dojo 1.7 stable release src.
I went into the buildScripts folder from the command line and tried to run a build with the following command:
>build profile=path/myMobileProfile.js action=release releaseName=test
I used the sample profile from the profiles folder:
dependencies = {
stripConsole: "normal",
layers: [
{
name: "dojo.js",
customBase: true,
dependencies: [
"dojox.mobile.parser",
"dojox.mobile",
"dojox.mobile.compat"
]
},
{
name: "../dojox/mobile/_compat.js",
layerDependencies: [
"dojo.js"
],
dependencies: [
"dojox.mobile._compat"
]
}
],
prefixes: [
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ]
]
}
It built with no errors. The dojo.js generated from the build was then dropped into my phonegap application. I changed my index file to the following just for testing:
<!DOCTYPE HTML>
<html>
<head>
<title>PhoneGap</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<meta http-equiv="cache-control" content="no-cache"/>
<meta http-equiv="pragma" content="no-cache"/>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojox/mobile/themes/android/android.css" type="text/css" media="screen" title="no title">
<script type="text/javascript" src="libs/dojo/dojo/dojo.js" djConfig="parseOnLoad:true"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.1.0.js"></script>
</head>
<body style="background-color:white">
Phonegap
</body>
</html>
Everytime I run the app I get a white page. When I replace the dojo.js file with my working copy I see the Phonegap output.
I would like to be able to use dojo 1.7 mobile and some of the new features such as the SpinWheel.
Can someone please help me with my build?
Thanks
I'm having the same type of issues. I think it has to do with the new AMD loader.
It seems as if the parser is not parsing the declarative widgets but rather is waiting to do it on demand or that it just never gets called.
I did find some docs that mention we should use dojo/ready, but couldn't get it to work with it and phoneGap. The same code works fine on a desktop without phoneGap, which is weird.
See live docs: http://livedocs.dojotoolkit.org/dojo/ready
As well as: http://livedocs.dojotoolkit.org/loader/amd
"To put the loader in the AMD mode, set the async configuration variable to truthy:
<script data-dojo-config="async:1" src="path/to/dojo/dojo.js"></script>
<script>
// ATTENTION: nothing but the AMD API is available here
</script>
Note that you can only set the async flag before dojo.js is loaded, and that in AMD mode, neither Dojo nor any other library is automatically loaded - it is entirely up to the application to decide which modules/libraries to load."
For me this Profile works fine with dojo 1.7 and PhoneGap:
dependencies = {
selectorEngine: "acme",
layers: [
{
// This is a specially named layer, literally 'dojo.js'
// adding dependencies to this layer will include the modules
// in addition to the standard dojo.js base APIs.
name: "dojo.js",
dependencies: [
"dijit._Widget",
"dijit._Templated",
"dojo.fx",
"dojo.NodeList-fx",
//this wasn't included in the standard build but necessary
"dojo._firebug.firebug",
//my used dojo requirements
"dojox.mobile.parser",
"dojox.mobile",
"dojox.mobile.Button",
"dojox.mobile.SwapView",
"dojox.mobile.ScrollableView",
"dojox.mobile.TabBar",
"dojox.mobile.SpinWheelTimePicker",
"dojox.mobile.compat"
]
}
],
prefixes: [
["dijit", "../dijit" ],
["dojox", "../dojox" ]
]
}
But with this Profil the CSS Files are not included, so you have to copy all the CSS folder structure.
My HTML file looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5.0//EN" "http://www.w3.org/TR/html5/strict.dtd">
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"></meta>
<meta name="apple-mobile-web-app-capable" content="yes"></meta>
<title>dojox.mobile Demo</title>
<link href="css/themes/iphone/iphone.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="phonegap.js" charset="utf-8"></script>
<script type="text/javascript" src="dojo.js" djConfig="isDebug:true, parseOnLoad:true"></script>
<script type="text/javascript">
require([
"dojox/mobile/parser", // (Optional) This mobile app uses declarative programming with fast mobile parser
"dojox/mobile", // (Required) This is a mobile app.
"dojox/mobile/Button",
//Some other dojo Widgets
"dojox/mobile/compat" // (Optional) This mobile app supports running on desktop browsers
],
function(parser, mobile, compat){
//Optional module aliases that can then be referenced inside callback block
}
// Do something with mobile api's. At this point Dojo Mobile api's are ready for use.
);
//to make sure dojo and PhoneGap was loaded use this
document.addEventListener("deviceready", init(), false);
function init(){
dojo.ready(function(){
//do something
});
}
</script>
</head>
<body>
</body>
HTH
This problem is solved with Dojo 1.7.2
Also found this: http://livedocs.dojotoolkit.org/dojo/parser
and tried to force parse on the entire dom or just the specific element, but still nothing.
I did find the following that may shed some more light on this issue: "Dojo and PhoneGap? both have their own event to acknowledge when the page is ready. We are finding that the dojo.ready is too early for things like deviceDetection APis when running within a PhoneGap? container and it would be better off being done inside of the PG deviceReady method. ..."
Full thread can be found here: http://bugs.dojotoolkit.org/ticket/14062
It is discussing dojo 1.6.1, but sounds like some changes in dojo 1.7 may suffer more severe reactions. There is a suggested workaround, but I'm not sure it will solve the 1.7 issue.

Categories