Nordth / dojo-webpack-loader

Webpack loader for Dojo Toolkit 1.x
MIT License
36 stars 11 forks source link

ESRI JS API 4.0 #7

Closed g3r4n closed 7 years ago

g3r4n commented 8 years ago

I'm trying to do a build of the ESRI JS API and i have the following errors :

ERROR in ./esri/widgets/Popup.js Module parse failed: D:\lab\dojo-webpack-loader-examples\node_modules\dojo-webpack-loader\index.js!D:\lab\dojo-webpack-loader-examples\ esri\widgets\Popup.js Unexpected character '@' (172:1) You may need an appropriate loader to handle this file type. SyntaxError: Unexpected character '@' (172:1) at Parser.pp$4.raise (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2221:15) at Parser.pp$7.getTokenFromCode (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2756:10) at Parser.pp$7.readToken (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2477:17) at Parser.pp$7.nextToken (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2468:15) at Parser.pp$7.next (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2413:10) at Parser.pp.eat (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:536:12) at Parser.pp$2.parseBindingList (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1425:18) at Parser.pp$1.parseFunctionParams (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1072:24) at Parser.pp$1.parseFunction (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1064:10) at Parser.pp$3.parseExprAtom (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1810:19) at Parser.pp$3.parseExprSubscripts (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1715:21) at Parser.pp$3.parseMaybeUnary (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1692:19) at Parser.pp$3.parseExprOps (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1637:21) at Parser.pp$3.parseMaybeConditional (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1620:21) at Parser.pp$3.parseMaybeAssign (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1597:21) at Parser.pp$3.parseExprList (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2165:22) at Parser.pp$3.parseSubscripts (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1741:35) at Parser.pp$3.parseExprSubscripts (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1718:17) at Parser.pp$3.parseMaybeUnary (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1692:19) at Parser.pp$3.parseExprOps (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1637:21) at Parser.pp$3.parseMaybeConditional (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1620:21) at Parser.pp$3.parseMaybeAssign (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1597:21) at Parser.pp$3.parseExpression (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1573:21) at Parser.pp$1.parseStatement (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:727:47) at Parser.pp$1.parseTopLevel (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:638:25) at Parser.parse (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:516:17) at Object.parse (D:\lab\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:3098:39) at Parser.parse (D:\lab\dojo-webpack-loader-examples\node_modules\webpack\lib\Parser.js:902:15) at DependenciesBlock. (D:\lab\dojo-webpack-loader-examples\node_modules\webpack\lib\NormalModule.js:104:16) at DependenciesBlock.onModuleBuild (D:\lab\dojo-webpack-loader-examples\node_modules\webpack-core\lib\NormalModuleMixin.js:310:10) @ ./esri/views/View.js 25:0-6182

You can do some test with my repo : https://github.com/g3r4n/dojo-webpack-loader-examples

lumen0988 commented 8 years ago

I also struggled with this on several other esri files. The reason is that the internal parser is not striping the comments when searching for the module body. It tries to find the first { within a file, which will lead to some weird module content when there is any { in the comment section before the define-block. As you can see in your case Esri-Popup the first { is in line 30 followed by an @ which leads to your error message. A solution for this is to replace line 37 var module_def_start = content.indexOf("{", function_match.index + function_match[0].length); with this var module_def_start = content.indexOf("{", define_match.index + define_match[0].length + function_match.index + function_match[0].length);

I hope someone can validate my solution and get it into one of the next releases.

gavinr commented 7 years ago

When I try to run @g3r4n's example, I get an error (as expected, based on his comment):

ERROR in ./esri/widgets/Popup.js
Module parse failed: C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\dojo-webpack-loader\index.js!C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\esri\widgets\Popup.js Une
xpected character '@' (172:1)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected character '@' (172:1)
    at Parser.pp$4.raise (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2221:15)
    at Parser.pp$7.getTokenFromCode (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2756:10)

    at Parser.pp$7.readToken (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2477:17)
    at Parser.pp$7.nextToken (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2468:15)
    at Parser.pp$7.next (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:2413:10)
    at Parser.pp.eat (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:536:12)
    at Parser.pp$2.parseBindingList (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1425:18)
    at Parser.pp$1.parseFunctionParams (C:\inetpub\wwwroot\github\dojo-webpack-loader-examples\node_modules\acorn\dist\acorn.js:1072:24)
...

After I change the line that @lumen0988 mentions above in node_modules\dojo-webpack-loader\internal\parser.js, I do NOT get a webpack error - yay! image

When I try to open the example page, however, I get this error in the console: VectorGroup.js:25 Uncaught TypeError: Cannot read property 'toLowerCase' of undefined(…) ..... VectorGroup.js:25

image

@lumen0988 are you getting the same error? Thanks!

lumen0988 commented 7 years ago

Hey there,

<TL;DR> Don't waste your time trying to get esri to work through webpack. It won't. What does work is to use dojo loader to load your webpack bundled source as amd module. </TL;DR>

I spend about two days to get esri JS 4.0 API working with webpack, ending up in total failure. In my experience it is impossible to get them working by principle. That's because dojo is built to load modules on runtime through loaders that can be loaded and chained dynamically on runtime, while webpack is a tool to statically analyze your dependency tree on build time and provide the resolved modules through webpack on runtime by id. The point where I resigned was the dojox/gfx module, which uses dojo’s custom-loader syntax by requiring "./gfx/renderer!". This usage is somehow weird because the custom-loader actually doesn’t load any other module. What it actually does is, it looks up at runtime which render methods e.g. svg, vml, Silverlight,… are supported by your browser and then conditionally requires/loads additional modules. This is nothing that can be achieved with wepback. Some research later I found that dojo is rebuild to a webpack-friendly version 2 but I don’t think that esri will adopt the new version somewhere soon. What I decided to do to get the benefits of wepack and the functionality of esri is to use dojo as the actual loader on runtime and to build my projects source via webpack as amd module which is then loaded as entry point by the dojo loader. Not the best solution but it works quiet well.

tomwayson commented 7 years ago

@lumen0988 thanks for the field report. Sounds like the .gfx/renderer plugin either uses or works like dojo/has. The Dojo build is a complicated beast, and I think replicating something like Dojo's has-aware build system in webpack could possibly be done, but would be a lot of work and not worth it given that there are workarounds as you describe.

I agree that the best way is to use a pre-built distribution (CDN or local) of the ArcGIS API and use webpack to bundle the non-Dojo code (your application code and any other vendor dependencies). There are several repos that show how to do this. I've also published the esri-loader library as an alternative workaround to this problem that has the benefit of being able to lazy-load the ArcGIS API and it's modules. I explain and compare these two approaches in this blog post as well as link to several repos that demonstrate how to implement them.