requirejs / r.js

Runs RequireJS in Node and Rhino, and used to run the RequireJS optimizer
Other
2.57k stars 674 forks source link

Module resolution ignores baseUrl #755

Open cowwoc opened 9 years ago

cowwoc commented 9 years ago

According to https://github.com/jrburke/r.js/blob/master/build/example.build.js, module names are resolved relative to baseUrl if it is set or relative to the directory holding the build file if it is not set.

In practice, what I am seeing is that relative paths are always being applied relative to Gruntfile.js (baseUrl is ignored).

I am running with require-js 2.1.15 and grunt-contrib-requirejs 0.4.4 with the following configuration:

grunt-contrib-requirejs configuration:

module.exports = function(grunt)
{
    var projectBuildDirectory = "../../../target/classes/";
    grunt.initConfig(
        {
        requirejs:
                {
                    compile:
                        {
                            options:
                                {
                                    baseUrl: projectBuildDirectory,
                                    optimize: "none",
                                    mainConfigFile: projectBuildDirectory + "js/RequireConfig.js",
                                    modules:
                                        [
                                            {
                                                name: "js/html/page/Index",
                                                // WORKAROUND: https://github.com/guybedford/require-css/issues/63#issuecomment-16086265
                                                excludeShallow: ["css/normalize", "require-css/css-builder"],
                                            }
                                        ],
                                    dir: projectBuildDirectory + "../out",
                                    onModuleBundleComplete: function(data)
                                    {
                                        var fs = require("fs");
                                        var amdclean = require("amdclean");
                                        var outputFile = data.path;

                                        fs.writeFileSync(outputFile, amdclean.clean(
                                            {
                                                filePath: outputFile
                                            }));
                                    }
                                }
                        },
                    done: function(done, output) {
                        var duplicates = require('rjs-build-analysis').duplicates(output);
                        if (duplicates.length > 0)
                        {
                            grunt.log.subhead('Duplicates found in requirejs build:');
                            grunt.log.warn(duplicates);
                            return done(new Error('r.js built duplicate modules, please check the excludes option.'));
                        }

                        done();
                    }
                }
        });
    grunt.loadNpmTasks("grunt-contrib-requirejs");
    grunt.registerTask("build", ["requirejs"]);

js/RequireConfig.js:

/* global log4javascript:false, require:false */

// See http://stackoverflow.com/a/22745553/14731
var scripts = document.getElementsByTagName("script");
var thisScriptTag = scripts[scripts.length - 1];
var dataMain = thisScriptTag.getAttribute("data-main");
require.config(
    {
        baseUrl: ".",
        paths:
            {
                // See http://requirejs.org/docs/jquery.html
                jquery: "webjars/jquery/2.1.1/jquery",
                "jquery-ui": "webjars/jquery-ui/1.11.1/jquery-ui",
                "webjars/jquery-address": "webjars/cowwoc-jquery-address/1.6/jquery.address",
                font: "webjars/requirejs-plugins/1.0.2/font",
                propertyParser: "webjars/requirejs-plugins/1.0.2/propertyParser",
                // Webjar libraries
                "webjars/q": "webjars/q/1.1.2/q",
                "webjars/requirejs-domready": "webjars/requirejs-domready/2.0.1/domReady",
                "webjars/cowwoc-alphanum-sort": "webjars/cowwoc-alphanum-sort/1.0.0/alphanum-sort",
                "webjars/log4javascript": "webjars/log4javascript/1.4.10/log4javascript",
                "webjars/prefixfree": "webjars/prefixfree/b44a065/prefixfree",
                "webjars/prefixfree/dynamic-dom": "webjars/prefixfree/b44a065/prefixfree.dynamic-dom",
                "webjars/sugar": "webjars/sugar/1.4.1/sugar-full.development",
                "webjars/semantic-ui/js": "webjars/Semantic-UI/1.2.0/semantic",
                "webjars/stacktrace": "webjars/stacktrace/0.6.0/stacktrace",
                "webjars/es6-shim": "webjars/es6-shim/0.12.0/es6-shim",
                "webjars/uri": "webjars/URI.js/1.12.0/URI",
                // Referenced by webjars/uri
                "webjars/IPv6": "webjars/URI.js/1.12.0/IPv6",
                "webjars/punycode": "webjars/URI.js/1.12.0/punycode",
                "webjars/SecondLevelDomains": "webjars/URI.js/1.12.0/SecondLevelDomains",
                // WORKAROUND: https://github.com/moment/moment/issues/2027
                //             https://github.com/moment/moment/issues/1095
                moment: "webjars/momentjs/2.7.0/moment",
                // CSS resources must have a different key than JS resources to avoid collisions
                "webjars/semantic-ui/css": "webjars/Semantic-UI/1.2.0/semantic",
                "webjars/jquery-ui/css": "webjars/jquery-ui/1.11.1/jquery-ui"
            },
        shim:
            {
                "webjars/log4javascript":
                    {
                        // See http://stackoverflow.com/a/18304309/14731
                        exports: "log4javascript",
                        /**
                         * Initializes the module.
                         */
                        init: function()
                        {
                            "use strict";
                            log4javascript.setDocumentReady();
                        }
                    },
                "jquery-ui": ["jquery"],
                "webjars/jquery-address": ["jquery"],
                "webjars/prefixfree":
                    {
                        // See http://stackoverflow.com/a/18304309/14731
                        exports: "PrefixFree"
                    },
                "webjars/cowwoc-alphanum-sort":
                    {
                        exports: "alphanum"
                    },
                "webjars/semantic-ui/js":
                    {
                        deps: ["jquery", "webjars/jquery-address"]
                    }
            },
        map:
            {
                // WARNING: When loading a module, RequireJS scans its path from right to left for the
                //   longest substring that will match an entry in "paths". If a match is found, the path
                //   component is replaced with the value of the entry. Therefore, if we define a mapping
                //   for "css", any module whose path begins with "css" will resolve relative to that path.
                //   See https://github.com/jrburke/requirejs/blob/2.1.15/require.js#L1614 and
                //   https://github.com/jrburke/requirejs/issues/1164
                //
                //   Because plugins names are short and they are added to "paths", they are quite likely
                //   to conflict. Our plan is to rename the plugin if such a conflict arises in the future.
                "*":
                    {
                        requireCss: "webjars/require-css/0.1.8/css"
                    }
            }
    });
if (dataMain)
    require([dataMain]);

Any ideas?

cowwoc commented 9 years ago

The specific error I am getting is:

{ [Error: Error: ENOENT, no such file or directory 'C:\Users\Gili\Documents\foo\frontend\src\test\out\js\html\page\Index.js'
    at Object.fs.openSync (fs.js:427:18)
]
  originalError: 
   { [Error: ENOENT, no such file or directory 'C:\Users\Gili\Documents\foo\frontend\src\test\out\js\html\page\Index.js']
     errno: 34,
     code: 'ENOENT',
     path: 'C:\\Users\\Gili\\Documents\\foo\\frontend\\src\\test\\out\\js\\html\\page\\Index.js',
     syscall: 'open' } }

I noticed something else. The optimizer seems to be processing that path twice. Once as an input file, and once as an output file. Meaning, this is one of the may input files the optimizer is combining and it ends up combining them over the same filename. Maybe that is triggering this problem somehow.

jwbay commented 9 years ago

Different error, but wondering if an issue I found could be related: https://github.com/jrburke/r.js/issues/768