jQWidgets Forums

jQuery UI Widgets Forums ASP .NET MVC Webpack 2: shimming like RequireJS?

This topic contains 7 replies, has 2 voices, and was last updated by  ownerer 7 years, 7 months ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
  • Webpack 2: shimming like RequireJS? #95984

    ownerer
    Participant

    Hi there,

    I’m migrating from a RequireJS project to Webpack.
    The latter is new to me, I’m using this as a learning exercise.

    In RequireJS I could register stuff like this:

    shim: {
    	'jqxcore': {
    		exports: "$",
    		deps: ["jquery"]
    	},
    	'jqxtree': {
    		exports: "$",
    		deps: ["jquery", "jqxcore"]
    	},
    	'jqxbutton': {
    		exports: "$",
    		deps: ["jquery", "jqxcore"]
    	},
    	'jqxsplitter': {
    		exports: "$",
    		deps: ["jquery", "jqxcore"]
    	},
    	'jqxmenu': {
    		exports: "$",
    		deps: ["jquery", "jqxcore"]
    	}
    }

    and then just require “jqxsplitter” for example like so:

    import "jqxsplitter"

    and stuff would be correctly registered and loaded.

    Now I was looking at a couple of guides/tutorials/takes I found on migrating from RequireJS to Webpack, such as this one and this one.

    So following those insights I’m trying something like this in my webpack.config.js:

    "use strict";
    
    // Required to form a complete output path
    const path = require("path");
    
    // Plagin for cleaning up the output folder (bundle) before creating a new one
    const CleanWebpackPlugin = require("clean-webpack-plugin");
    
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const webpack = require("webpack");
    
    // Path to the output folder
    const bundleFolder = "./wwwroot/";
    
    // Path to the app source code
    const appFolder = "./app/";
    
    module.exports = {
    	// Application entry point
    	entry: {
    		main: appFolder + "index.ts",
    		vendor: [
    			"knockout",
    			"jquery",
    			"jqxcore"
    		],
    		jqxsplitter: "jqxsplitter"
    	},
    
    	// Output file
    	output: {
    		filename: "[name].js",
    		chunkFilename: "[name].js",
    		path: path.resolve(bundleFolder)
    	},
    	module: {
    		rules: [{
    			test: /\.tsx?$/,
    			loader: "ts-loader",
    			exclude: /node_modules/
    		}, {
    			test: /\.html?$/,
    			loader: "html-loader" //TODO: file-loader?
    		}],
    		loaders: [{
    			test: /jqxcore/,
    			loader: "imports?jquery!exports?$"
    		}, {
    			test: /jqxsplitter/,
    			loader: "imports?jquery,jqxcore!exports?$"
    		}]
    	},
    	resolve: {
    		extensions: [".tsx", ".ts", ".js"],
    		alias: {
    			"jqxcore": "jqwidgets-framework/jqwidgets/jqxcore",
    			"jqxsplitter": "jqwidgets-framework/jqwidgets/jqxsplitter"
    		}
    	},
    	plugins: [
    		new CleanWebpackPlugin([bundleFolder]),
    		new HtmlWebpackPlugin({
    			filename: "index.html",
    			template: appFolder + "index.html",
    			chunks: ["main", "vendor"]
    		}),
    		new webpack.optimize.CommonsChunkPlugin({
    			name: "vendor",
    			filename: "vendors.js",
    			minChunks: Infinity
    		})
    	],
    	devtool: "source-map"
    };

    the relevant part (I assume) being

    module: {
    	loaders: [{
    		test: /jqxcore/,
    		loader: "imports?jquery!exports?$"
    	}, {
    		test: /jqxsplitter/,
    		loader: "imports?jquery,jqxcore!exports?$"
    	}]
    },

    It’s pretty clear how the syntax of “imports/exports” is supposed to be the equivalent of RequireJS’ “deps” and “exports”.
    However when I do this in my index.ts file (app root):

    import "jqwidgets-framework/jqwidgets/jqxsplitter";

    I get the “jqxBaseFramework is undefined” error when running my app.
    I’ve found references to this error on the forums here, but none of the answers seem to REALLY tackle the issue or include things like the AOT compilation, which doesn’t apply to my situation because I’m not using Angular.

    Any ideas?

    PS: the only reason this is in the ASP.NET forum is because I’m running it in a .NET Core project, didn’t know where else to put it, but that shouldn’t matter of course.

    Webpack 2: shimming like RequireJS? #95985

    Peter Stoev
    Keymaster

    The base framework is defined in jqxcore.js. So if you get this error this means that your scripts are not loaded in order i.e jqxcore.js is still not loaded at the moment you try to use some widget.

    Best Regards,
    Peter Stoev

    jQWidgets Team
    https://www.jqwidgets.com/

    Webpack 2: shimming like RequireJS? #95987

    ownerer
    Participant

    Well yeah ok, of course, I know that.
    In its most basic form you would include script tags in the order 1.jquery, 2.jqxcore, 3.jqxwhateverplugin.

    That’s what RequireJS does under the hood by saying jqxcore has a dependency on jquery (ie: load jquery before jqxcore because jqxcore needs it), and jqxwhateverplugin has a dependency on both of those (ie: load both jqxcore and jquery because it needs both).
    So the order of script loading is handled by RequireJS.

    In the same way I want it and would expect it to be handled by Webpack, but clearly it doesn’t.
    Or at least not the way I’m trying.

    Let me be clear: I do NOT want to be including manual script tags on any pages.
    There should be a way to tell Webpack it needs to load jqxcore and jquery first when requireing jqxwhateverplugin, just the way RequireJS does.
    Otherwise what’s the point…

    So how does one go about doing that :)?

    Webpack 2: shimming like RequireJS? #96036

    ownerer
    Participant

    Any feedback?
    I can’t imagine that no one has ever done this before…

    Webpack 2: shimming like RequireJS? #96089

    ownerer
    Participant

    Anyone?

    Webpack 2: shimming like RequireJS? #96333

    ownerer
    Participant

    posted here on Stackoverflow as well since no one seems to answer here.

    Webpack 2: shimming like RequireJS? #96382

    Peter Stoev
    Keymaster

    May be the correct syntax should be import “jqwidgets-framework/jqwidgets/jqxsplitter.js”; not import “jqwidgets-framework/jqwidgets/jqxsplitter”;

    Webpack 2: shimming like RequireJS? #96390

    ownerer
    Participant

    That’s not it, wouldn’t make sense either since the script is clearly being loaded that way, otherwise I wouldn’t be getting that error in the first place.

    Anyway, this was taking too long so I decided to deep dive and figure it out myself.
    The answer can be found here.

Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.