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

Question about compilation. #1

Open
jordwalke opened this issue Jun 9, 2013 · 12 comments
Open

Question about compilation. #1

jordwalke opened this issue Jun 9, 2013 · 12 comments

Comments

@jordwalke
Copy link

This project is very cool. I'll certainly end up using this. Will require.js ensure that the compilation happens on the server as part of the build step? If not, is there some way that we can message to users that compilation in the browser should not be done in production (due to the huge bloat of file size caused by including the compiler and the CPU required to compile)?

@seiffert
Copy link
Owner

seiffert commented Jun 9, 2013

Hi @jordow and thanks for the feedback!
Sadly, I wasn't able to get the compilation with r.js to work so far. I've spent a couple of hours in the #reactjs chat with @petehunt and @zpao on this topic, but we weren't able to find a good solution in the end. The problem seems to be that the built version of JXSTransformer includes require calls that aren't compatible with require.js - which normally shouldn't be a problem. In this case however, it leads to a mismatched anonymous define() error in the browser (after a successful compilation on the server).

This require.js plugin should definitely notify the user not to use in-browser-JXS-transformation in production. Do you have a better idea than just writing this message to the browsers JS console?

@jordwalke
Copy link
Author

Browser console is a good start.

@camspiers
Copy link

I've been able to get the compiled jsx in a built version with r,js using PR #5 and a build config that has the following: (note this isn't the full config, just the relevant parts)

({
    exclude: ['JSXTransformer', 'jsx'],
    include: ['jsx!app'],
    onBuildWrite: function (moduleName, path, singleContents) {
        return singleContents.replace(/jsx!/g, '');
    }
})

What is does is write the compiled version to the file with 'jsx!' removed whenever found. So something like:

define('Component1', ['jsx!Component2'], function (Component2) {});

becomes:

define('Component1', ['Component2'], function (Component2) {});

This isn't the best solution due to the potential to replace instances of 'jsx!' where it isn't desirable, but it is at least working.

@ssorallen
Copy link

@camspiers Can you elaborate on your build setup? Despite excluding JSXTransformer and jsx, I am getting errors since jsx depends on JSXTransformer. I am using your patch from #5:

Tracing dependencies for: main
Error: Parse error using esprima for file: /.../build/js/libs/JSXTransformer.js
Error: Line 11478: Unexpected token if
In module tree:
    main
      jsx

Error: Error: Parse error using esprima for file: /.../build/js/libs/JSXTransformer.js
Error: Line 11478: Unexpected token if
In module tree:
    main
      jsx

    at /usr/local/share/npm/lib/node_modules/requirejs/bin/r.js:23648:47

@camspiers
Copy link

My amd.config.js looks like this:

require.config({
    baseUrl: 'source/js',
    paths: {
        JSXTransformer: '../bower_components/react/JSXTransformer',
        jsx: '../bower_components/require-jsx/jsx',
        react: '../bower_components/react/react',
        almond: '../bower_components/almond/almond'
    }
});

My amd.build.js looks like this:

({
    baseUrl: '.',
    mainConfigFile: 'amd.config.js',
    name: 'almond',
    out: '../../prod/app.js',
    exclude: ['JSXTransformer', 'jsx'],
    include: ['jsx!app'],
    onBuildWrite: function (moduleName, path, singleContents) {
        return singleContents.replace(/jsx!/g, '');
    },
    preserveLicenseComments: false
})

bower.json like this:

{
    "name": "app",
    "version": "0.0.0",
    "dependencies": {
        "rjs": "2.1.8",
        "react": "0.4.1",
        "almond": "0.2.6",
        "require-jsx": "git://github.com/camspiers/require-jsx.git#patch-1"
    }
}

And the command I am running is:

node bower_components/rjs/dist/r.js -o js/amd.build.js

Excuse the old versions, the project was a while ago.

Hope this helps!

@felipecrv
Copy link

@ssorallen this error is caused by some preprocessing that removes 'use strict' from JSXTransformer.js.

In the original file, ... === 'use strict'becomes ... ===. Such a mess!

@felipecrv
Copy link

I figured out how to make it work.

Used @camspiers config:

({
    exclude: ['JSXTransformer', 'jsx'],
    include: ['jsx!app'],
    onBuildWrite: function (moduleName, path, singleContents) {
        return singleContents.replace(/jsx!/g, '');
    }
})

And replaced occurrences of 'use strict' by 'use ' + 'strict' when it's used as a value in JSXTransformer.js.

@ssorallen
Copy link

And replaced occurrences of 'use strict' by 'use ' + 'strict' when it's used as a value in JSXTransformer.js.

@philix, that sounds like the bit I was missing. Thanks for pointing that out. I will give that a shot and see if that fixes my build.

@maglar0
Copy link

maglar0 commented Mar 25, 2014

I still couldn't get it working the way described above, but used the ideas to solve it in (what I think is) a different way. I remove "jsx!" and do the JSX->JS transformation myself before handing the files over to r.js and almond. I have my files in ./app, ./app/jsx (this is where the JSX files live) and ./lib. My requirejs config is like this:

requirejs.config({
    baseUrl: "/js2/lib",
    paths: {
        app: "/js2/app",
        appjsx: "/js2/app/jsx",
        jsx: "jsx",
        JSXTransformer: "JSXTransformer"
    },
    shim: {
        exports: "JSXTransformer"
    }
});

and my build.js file is like this:

({
    baseUrl: "../build",
    out: "main-built.js",
    name: "lib/almond",
    include: ["app/a"],
    exclude: [],
    preserveLicenseComments: false,
    generateSourceMaps: true,
    optimize: "uglify2",
    insertRequire: ["app/a"],
    onBuildWrite: function(moduleName, path, singleContents) {
        return singleContents
            .replace(/console\.(log|assert)\([^))]*\);/g, "");
    },
    paths: {
        appjsx: "jsx"
    }
})

and my Makefile can be found at https://gist.github.com/maglar0/9762505 .

@felipecrv
Copy link

@maglar0 what are the error messages? r.js fails for all sorts of reasons. If you're getting undefined is not a function message you should probably disable sourceMap in JSXTransformer as I did here.

facebook/react#972 may help too.

@maglar0
Copy link

maglar0 commented Mar 26, 2014

@philix It works when I set sourceMap to false as you did in that link, together with the earlier change of === 'use strict' to === 'use '+'strict'. Thanks for the effort you have put into solving this, I got totally nonsensical error messages like "undefined is not a function" without any reference to line numbers so didn't know where to start at all.

However, I strongly prefer not to fork JSXTransformer.js and the source map of the output when doing it this way references nonsense files like "../app/jsx/d!jsx", thus I will continue to do the JSX transform myself and then hand over the files to r.js.

@felipecrv
Copy link

@maglar0 your approach avoids a lot of headaches 👍

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

6 participants