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'
}
}
};
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??