I'm trying to load a lot of our JS dependencies using requirejs. We are having an issue with the dependency that KnockoutSortable has on jquery-ui\sortable.
I can not get sortable.js to come from the cdn download of jquery-ui it is satisfying it's dependency by downloading from the copy within my site. I have tried to shim
'knockoutSortable' : {
deps: ['jqueryUi']
},
but that has not forced Knockout to use the CDN downloaded version of jquery-ui
Our configuration is as follows:
var require = {
baseUrl: '/Scripts',
paths: {
jquery: ['//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min', 'lib/jquery-1.9.1.min'],
jqueryUi: ['//ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min', 'lib/jquery-ui-1.11.3.min'],
knockout: ['//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min','lib/knockout-3.3.0.min'],
knockoutMapping: ['//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min','lib/knockout.mapping-latest.min'],
knockoutValidation: ['//cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.2/knockout.validation.min','lib/knockout.validation.min'],
knockoutPostBox: ['//cdnjs.cloudflare.com/ajax/libs/knockout-postbox/0.5.1/knockout-postbox.min', 'lib/knockout-postbox.min'],
knockoutSortable: ['//cdnjs.cloudflare.com/ajax/libs/knockout-sortable/0.11.0/knockout-sortable.min','lib/knockout-sortable.min'],
...
shim: {
'jquery': {
exports: '$'
},
'knockoutSortable' : {
deps: ['jqueryUi']
},...
Since jquery-ui and knockout both AMD compatible you can't use a shim configuration you need to use a map config instead to map jquery-ui modules back to the jqueryUi path.
See link
We solved this by adding this map configuration to the require.config
map : {
'*': {
'jquery-ui/core': 'jqueryUi',
'jquery-ui/sortable': 'jqueryUi',
'jquery-ui/draggable': 'jqueryUi',
'jquery-ui/mouse': 'jqueryUi',
'jquery-ui/widget': 'jqueryUi'
}
}
Related
I have a legacy application built in ASP.NET 4.8 MVC.
I would like to start building some client side features in Svelte - having svelte components rendering inside razor views. This I have working. I can render a svelte component anywhere in the razor page.
However vite has some problem (im guessing with HMR?), and it keeps refreshing the razor page (https://localhost:44300/somefeature) every few seconds.
Environment
asp.net 4.8 mvc loads to https://localhost:44300/
vite is loading on http://localhost:3000/
Here is what i have so far. I ran npm init vite#latest -> selected svelte + svelte TS
vite.config.js
import { defineConfig } from 'vite'
import { svelte } from '#sveltejs/vite-plugin-svelte'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
svelte({
compilerOptions: {
customElement: true,
}
})
],
build:{
// generate manifest.json in outDir
manifest: true,
rollupOptions: {
// overwrite default .html entry
input: '/src/main.ts'
}
}
})
Then i followed the instructions here https://vitejs.dev/guide/backend-integration.html and added this to the razor page:
#Html.Raw("<script type='module' src='http://localhost:3000/#vite/client'></script>")
<script type="module" src="http://localhost:3000/src/main.ts"></script>
(Note - had to use Html.Raw because it wouldnt let me escape the # correctly - even with ##)
At this point it is rendering my Svelte component perfectly.
The issue however is that vite is now reloading my page every 2 seconds or so - im guessing because HMR is no longer working correctly as the console just says: [vite] connecting...
Can anyone point me in a direction either to get HMR working whilst using another Backend server? For some reason it works in asp.net core, but not so in ASP.NET 4.8. Any observations to help?
Thanks in advance!
Ok i got it working. Here is my vite.config.js. Pay special attention to the
input, outDir and server nodes, and adjust them to your scenario. The proxy is important, you can either set it to your https or http mvc endpoint and port that asp.net spins up for you.
Here is the config:
export default defineConfig({
plugins: [
svelte()
],
build:{
// generate manifest.json in outDir
manifest: true,
rollupOptions: {
// overwrite default .html entry
input: 'Scripts/svelte/app.js',
},
outDir: 'Scripts/svelte/dist'
},
server: {
proxy:{
'*' : {
target: 'http://localhost:26688',
changeOrigin: true
}
},
hmr: {
protocol: 'ws'
}
}
})
Its pretty cool - you get instant HMR of any svelte component inside a razor page without losing any razor state.
THANK YOU!!!! This is exactly what I was looking for to include my react code in my old Asp.Net 4.8 site with hot module reload!
For other's the thing I had to include in my cshtml to make the react stuff load properly was:
<script type="module">
import RefreshRuntime from "http://localhost:9999/##react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>
If you don't include this you get an error saying '#vitejs/plugin-react can't detect preamble'.
I am hosting the development site in IIS locally so to serve up the local files, I just created a /src folder off of the root or my application pointing to the src in my react directory and it worked beautifullly!!
I need to migrate bundleConfig from an old asp.net project mvc to asp.net core
I added in startup.cs:
app.UseBundling (
// as we rebased the static files to / static (see UseStaticFiles ()),
// we need to pass this information to the bundling middleware as well,
// otherwise urls would be rewrited incorrectly
new BundlingOptions
{
StaticFilesRequestPath = "/static"
},
bundles =>
{
bundles.AddJs ("/bundles /jquery")
.Include ("/Scripts/jquery-{version}.js");
bundles.AddCss ("/bundles/jquery")
.Include ("/Scripts/jquery-{version}.js");
// we use LESS in this demo
bundles.AddCss ("/site.css")
.Include ("/less/site.less");
// defines a Javascript bundle containing your Vue application and components
bundles.AddJs ("/app.js")
.Include ("/js/components /*.Js")
.Include ("/js/app.js");
});
If you are using .Net core, bundleconfig.cs is gone.
Follow the steps below to add bundling and minification
Install the bundler and minifier extension in visual studio
Add bundleconfig.json to you solution
Based on your bundles modify file, something like below
[
{
"outputFileName": "wwwroot/bundles/bootstrap",
"inputFiles": [
"Scripts/bootstrap.js"
]
},
{
"outputFileName": "wwwroot/css/site.min.css",
"inputFiles": [
"wwwroot/css/site.css",
"Content/bootstrap.css"
],
"minify": {
"enabled": true,
"renameLocals": true
},
"sourceMap": false
},
{
"outputFileName": "wwwroot/js/semantic.validation.min.js",
"inputFiles": [
"wwwroot/js/semantic.validation.js"
],
"minify": {
"enabled": true,
"renameLocals": true
}
}
]
You can automate the bundling and minification as part of build process as well with dotnet bundle command ( However this part I have not done yet, so not idea on this)
You would have to create a cs file in App_Start
using System.Web.Optimization;
namespace EnterYourProgramsNameSpaceHere
{
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
//Add your bundles here
bundles.Add(new StyleBundle("~/Content/myStyle")
.Include("~/Content/styles.css"));
bundles.Add(new ScriptBundle("~/bundles/myjs")
.Include("~/Scripts/jquery.js"));
}
}
}
in startup.cs
add this line
BundleConfig.RegisterBundles(BundleTable.Bundles);
You have to make sure that the spacing in your file paths is removed, in your example the program may have an issue finding your js/css files.
you can look up more info here : http://go.microsoft.com/fwlink/?LinkId=301862
In my _layout.cshtml I have a partial view that includes js trough requirejs.
<script data-main="/Scripts/Search" src="/Scripts/require.js"></script>
In this js file I use the following to populate a knockout vm.
$.getJSON("/Search/Index", function (data) {
self.availableCities(data.AvailableCities);
});
This works well on all pages except when my main view also has an ajax request.
<script data-main="/Scripts/Index" src="/Scripts/require.js"></script>
$.getJSON("/Property/All", function (data) {
self.properties(data);
});
Here is my require config, it is the same for the partial and the main view.
require.config({
baseUrl: "/Scripts",
paths: {
"text": "text",
"knockout": "knockout-3.3.0",
"jquery": "jquery-2.1.3.min"
},
shim: {
"jquery": { exports: "$" }
}
});
When the main page has an ajax request only this request is fired, I am not sure how to fix this. It looks like a configuration issue, tested it in both Firefox an Chrome so it does not appear to be browser specific.
It turns out having multiple <script data-main="/Scripts/Search" src="/Scripts/require.js"></script> tags in one page isn't such a bright idea.
I figured it out after some more research,
this question has a good solution if you run into a similar problem.
Basically you need one 'main.js' file and add the other page components via the require logic.
Edit:
Doing this may result in the following knockout error:
Error: You cannot apply bindings multiple times to the same element.
To fix this I have used the following binding handler:
ko.bindingHandlers.stopBinding = {
init: function () {
return { controlsDescendantBindings: true };
}
};
To enable this binding handler on containerless elements use the following:
ko.virtualElements.allowedBindings.stopBinding = true;
Apply the following binding around the partial view. To prevent the main-page from binding to the elements in the partial.
<!-- ko stopBinding: true-->
<!-- /ko -->
Finally use ko.applyBinings on the partialview like this:
ko.applyBindings(new partialViewModel(), document.getElementById("your-partial"));
The syntax for dependency injection in Angular.js is confusing me.
I have a Rails app that is using Angular. One of the directives needs to use the $cookies service. So I have the main Javascript file where I declare the angular app, and a directives folder with js-files for my directives.
So this is the relevant part of the main js file. I'm trying to inject the ngCookies module into it:
app.js
angular.module('myApp', [
'templates',
'ngCookies'
]);
and here is the file with the directive that needs the $cookies service:
my-directive.js
angular.module('myApp')
.directive("myDirective", ['$cookies', function(){
return {
restrict: 'E'
templateUrl: "my-directive-template.html",
scope: {
article: '=ngModel'
},
link: function(scope, element, attrs){
scope.myFunction = function(){
$cookies.example = "hello world"; // set a cookie
};
}
};
}]);
So I'm trying to inject the ngCookies module into the myApp module and then inject the $cookies service into the directive.
This syntax doesn't work; Firebug gives me an error: "Error: $cookies is undefined".
Could you please help me figure out how to inject dependencies in Angular properly?
Oh my! I guess the only thing I needed was to add the $cookies as an attribute for the function declaration as well so that the line
.directive("myDirective", ['$cookies', function(){
became
.directive("myDirective", ['$cookies', function($cookies){
It seems that requireJS does not work properly with jquery mobile 1.4.2
in the app.js I have the minimum configuration for RequireJS 2.1.11
requirejs.config({
'baseUrl': 'js',
'paths': {
'jquery': 'lib/jquery-1.10.2',
'jquerymobile': 'lib/jquery_mobile/jquery.mobile-1.4.2'
}
});
And then when I am trying to use jquerymobile dependancy I have:
define(['require', 'jquery', 'jquerymobile' ], function (require, $) {
console.log(success)
})
This shows an error in the Chrome console
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:63342/app/www/js/demos/js/jquery.js
Uncaught Error: Script error for: demos/js/jquery
http://requirejs.org/docs/errors.html#scripterror require.js:141
This is caused by jquery mobile code:
(function ( root, doc, factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( [ "demos/js/jquery" ], function ( $ ) {
factory( $, root, doc );
return $.mobile;
});
} else {
// Browser globals
factory( root.jQuery, root, doc );
}
}
When I change with jquery mobile 1.3.2 it seems that require JS is working correctly. Is there a way to use requireJS with Jquery mobile 1.4.2 ?
You're not using the correct source. When I go straight to the official source, I see:
(function ( root, doc, factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( [ "jquery" ], function ( $ ) {
factory( $, root, doc );
return $.mobile;
});
} else {
This is exactly what I would expect: jQuery Mobile depends on jquery, which is the way you always should require jQuery with RequireJS.
The demos/js/jquery dependency that you see in the code you show in your question does not make much sense. It would be possible to make it work but it would require everybody who uses jQuery Mobile to go through an unnecessary configuration hoop. This is a big red flag that something is wrong.