Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not working with webpack very well. #39

Open
crashnick16 opened this issue Apr 26, 2018 · 4 comments
Open

not working with webpack very well. #39

crashnick16 opened this issue Apr 26, 2018 · 4 comments

Comments

@crashnick16
Copy link

crashnick16 commented Apr 26, 2018

I am getting the below error every time I build with webpack:

Critical dependency: the request of a dependency is an expression

Any ideas how this can be fixed?

@rniemeyer
Copy link
Owner

@crashnick16 - do you have a sample of your webpack config and/or folder structure.

Using webpack v4 with knockout-amd-helpers v1.0.0, a sample entry point looks like this:

var ko = require( "knockout" );
require( "knockout-amd-helpers" );

var moduleContext = require.context( "./mods" );
var templateContext = require.context( "html-loader!./templates" );

ko.bindingHandlers.module.loader = function( moduleName, done ) {
	var mod = moduleContext( "./" + moduleName );
	done( mod );
}

ko.amdTemplateEngine.loader = function( templateName, done ) {
	var template = templateContext( "./" + templateName + ".html" );
	done( template );
}

ko.applyBindings( {
	firstName: "Top",
	lastName: "Last"
} );

@kevin074
Copy link

kevin074 commented Oct 12, 2018

Hi I am looking at the same errors, I've also copy and pasted + modified the code you have provided above.
"webpack": "^4.20.2"
knockout-amd-helpers 1.0.0

my project is as such

myApp:
  js/
    app.js (has code above)
    libs/
    modules/
  img/
  css/
  html/
  webpack.config.js
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin')

const distFolder = path.resolve(__dirname, 'dist')

module.exports = {
    entry: path.resolve(__dirname, 'js/app.js'),
    output: {
        filename: 'main.[contenthash].js',
        path: distFolder
    },
    devtool:'eval',
    mode: 'none',
    module:{
        rules:[
            {
                test: /\.html$/,
                loader: "html-loader"
            },
        
        ]
    },
    resolve:{
        alias:{
            'knockout-amd-helpers' : path.resolve(__dirname, 'js/libs/knockout-amd-helper'),
            knockout : path.resolve(__dirname, 'js/libs/knockout'),
            modules : path.resolve(__dirname, 'js/modules'),
            libs : path.resolve(__dirname, 'js/libs'),
            'text': path.resolve(__dirname, '/node_modules/text-loader')
        }
    },
    plugins:[
        new CleanWebpackPlugin(['dist']),
        new CopyWebpackPlugin([{from:'./html', to: 'html'}]),
        new HtmlWebpackPlugin({
            hash: true,
            template: 'index.html'
        }),
    ]
};

I have modified these to suit my structure
var moduleContext = require.context( "./" );
var templateContext = require.context( "html-loader!../html" );

is there something you can suggest to help me debug ? This is my first attempt to use webpack and I don't really understand how templating works in knockout inside out.
Thank you very much!

@fiidim
Copy link

fiidim commented Jan 24, 2025

Not sure if anyone is still listening on this thread, but I finally got this working with the most recent version of webpack (5.97.1). For posterity, here is what I did:

Prerequisites (package.json:

  • "webpack": "^5.97.0"
  • "html-loader": "^4.2.0"

Configuration (webpack.config.js) to configure the html-loader.

rules: [ 
...
            {
                test: /\.html$/,
                exclude: /node_modules/,
                use: {
                    loader: 'html-loader',
                },
            },
...
]

Override the default loader somewhere in code:

        var templateContext = require.context('../templates', true, /.html$/);
        (ko.amdTemplateEngine as any).loader = function (templateName, done) {
            var tname = `${ko.amdTemplateEngine.defaultPath}/${templateName}${ko.amdTemplateEngine.defaultSuffix}`;
            var template = templateContext(tname);
            done(template.default);
        }

What I found was that the templateContext (result of require.context) function returns a module, not the string contents of the template. There is a member "default" that has the contents, which is what you want.

Another thing to consider is where your templates are located at runtime. If you don't get the pathing right, the functions will fail.

@rniemeyer
Copy link
Owner

@fiidim Nice! Thanks for adding this info to the thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants