webpackcanjswebpack-dev-server

Using canjs with webpack


I am trying to use canjs with webpack. I am not able to get it working. Any help is appreciated.

I did the following:

Approach 1:

I installed canjs using npm and in my main.js

require('can');

Ran the webpack command. Did not work. The code was using steal and I read some articles they recommended installing canjs usinf bower.

Approach 2:

Installed canjs using bower now I have 4 different types of code within the canjs folder

amd
amd-dev
cjs // Common js
steal

I always use the amd one and I did the following.

`

var path = require('path'),
    root = path.resolve(__dirname),
    bowerPath = path.resolve(root, 'bower_components');


module.exports = {
    context: path.resolve(root, 'app'),
    entry: './main.js',
    output: {
        path: path.resolve(root, 'dist'),
        filename: 'bundle.js'
    },      
    resolve: {
        root: root,
        modulesDirectories: ['node_modules', 'amd'],
        alias: {
            'canjs': bowerPath + '/canjs/amd/can.js'
        }
    }
}

Ran the webpack command and got the following error

ERROR in ./bower_components/canjs/amd/can/util/dojo.js
Module not found: Error: Cannot resolve module 'dojo/main' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\amd\can\util
 @ ./bower_components/canjs/amd/can/util/dojo.js 11:0-482:2 24:4-99:6 100:4-105:6

ERROR in ./bower_components/canjs/amd/can/util/dojo.js
Module not found: Error: Cannot resolve module 'dojo/query' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\amd\can\util
 @ ./bower_components/canjs/amd/can/util/dojo.js 100:4-105:6

ERROR in ./bower_components/canjs/amd/can/util/dojo.js
Module not found: Error: Cannot resolve module 'dojo/NodeList-dom' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\amd\can\util
 @ ./bower_components/canjs/amd/can/util/dojo.js 100:4-105:6

ERROR in ./bower_components/canjs/amd/can/util/vdom/make_parser.js
Module not found: Error: Cannot resolve module 'simple-dom' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\amd\can\util\vdom
 @ ./bower_components/canjs/amd/can/util/vdom/make_parser.js 10:0-68:2

ERROR in ./bower_components/canjs/amd/can/util/yui.js
Module not found: Error: Cannot resolve module 'yui' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\amd\can\util
 @ ./bower_components/canjs/amd/can/util/yui.js 10:0-413:2

ERROR in ./bower_components/canjs/amd/can/util/zepto.js
Module not found: Error: Cannot resolve module 'zepto' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\amd\can\util
 @ ./bower_components/canjs/amd/can/util/zepto.js 10:0-328:2

ERROR in ./bower_components/canjs/amd/can/util/mootools.js
Module not found: Error: Cannot resolve module 'mootools' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\amd\can\util

 @ ./bower_components/canjs/amd/can/util/mootools.js 10:0-355:2

At this point, I gave up on the amd approach.

Approach 3:

Decided to use the common js instead. Removed the amd from the moduleDirectories and changed my alias to point to cjs folder.

webpack.config.js change:

   resolve: {
        root: root,
        modulesDirectories: ['node_modules'], // Removed 'amd'
        alias: {
            'canjs': bowerPath + '/canjs/**cjs**/can.js'
        }
    }

Ran the webpack command. Now I have only 2 errors.

WARNING in ./bower_components/canjs/cjs/view/view.js
Critical dependencies:
50:12-19 require function is used in a way in which dependencies cannot be statically extracted
51:18-25 require function is used in a way in which dependencies cannot be statically extracted
 @ ./bower_components/canjs/cjs/view/view.js 50:12-19 51:18-25

ERROR in ./bower_components/canjs/cjs/map/define/define.js
Module parse failed: c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\cjs\map\define\define.js Line 15: Illegal return statement
You may need an appropriate loader to handle this file type.
| require('../../compute/compute.js');
| if (can.define) {
|     return;
| }
| var define = can.define = {};
 @ ./bower_components/canjs/cjs/can.js 13:0-33

ERROR in ./bower_components/canjs/cjs/view/stache/add_bundles.js
Module not found: Error: Cannot resolve module '@loader' in c:\AxxessProjects\axxess-billing-services\Axxess.RCM.BillingServices.Site\bower_components\canjs\cjs\view\stache
 @ ./bower_components/canjs/cjs/view/stache/add_bundles.js 10:13-32

I dug a little deep into these 2 errors.

Error 1: The illegal return in map/define/define.js

Changed the if condition to if(!can.define) and moved the rest of the code inside the if condition and this fixed.

Error 2: @loader in view/stache/add_bundles.js

I found this statement in the above file

var loader = require('@loader/');

I am not sure what @loader is used for. I did not want to mess with it.

So, as you can see I was not able to successfully build canjs using webpack.

I am posting this to find out whether anyone has tried using canjs with webpack and succeeded.

Final Solution:

Followed approach 3 with changes suggested by @Charles.

My current webpack.config.js now

module.exports = {
    cache: true,
    stats: true,
    module: {
        loaders: [
            {
                test: /\.stache$/,
                loader: 'raw'
            }
        ]
    },
    resolve: {
        modulesDirectories: [
            'node_modules',
        ],
        extensions: ['', '.js'],
        alias: {
            'can$': 'can/dist/cjs/can.js',
            'can': 'can/dist/cjs'
        }
    }
};

Solution

  • I ran into the same issues you did in your 3rd approach. I was able to get around the problem in define.js by just commenting out the offending 'if' statement. For the @loader issue, I replaced that line with the following code and it worked:

    var loader = require('raw!');
    

    I also added a loader to my webpack.config.js for stache files:

    loaders: [
        { test: /\.stache$/, loader: "raw" }
    ]
    

    And added the raw-loader npm module:

    npm install --save-dev raw-loader
    

    In the bit of research I did on this, it appears that @loader is a StealJS thing (StealJS Docs)

    I'm guess the cjs version of can.js was based on the stealJS version and someone missed some conversions??