Closed NullVoxPopuli closed 8 years ago
I see that in system-config.ts we have '@angular': 'vendor/@angular'. This seems to be relative to the dist/ directory. Maybe you can try using directly app/components/stuff. Just a wild guess, as I'm new at this, still trying to figure things out.
I had also tried adding '@app': 'app', and it can't find any files using that. :-\
Also, I deleted the dist folder, so it appears that however this needs to be configured, it is pre-build (because the error occurs before the dist folder is even created)
you should use map + packages in system-config.js
/** Map relative paths to URLs. */
const map:any = {
'@web-app': './app/'
};
/** User packages configuration. */
const packages:any = {
'@web-app': {
format: 'cjs',
defaultExtension: 'js',
main: 'index'
}
};
Also tsconfig.json in compilerOptions section
"paths": {
"@web-app": ["./app/index.ts"],
"@web-app/*": [
"./app/*"
]
}
and then you can use something like that:
import {environment} from '@web-app';
Note: it works without -prod
option, with -prod
it toggles error:
$ ng build -prod
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
⠹ Building"{{content-for}}" has been deprecated and will be removed before RC.
Build failed.
The Broccoli Plugin: [BundlePlugin] failed with:
Error tracing app/+login/login.component.js at file:///Users/serhiysolonko/Development/Projects/web-app/tmp/bundle_plugin-input_base_path-kOVkldZW.tmp/0/app/+login/login.component.js
Loading app/+login/index.js
Loading app/web-app.component.js
Loading app/index.js
Loading main.js
Error: Unable to calculate canonical name to bundle file:///Users/serhiysolonko/Development/Projects/web-app/app//index.js. Ensure that this module sits within the baseURL or a wildcard path config.
at getCanonicalNamePlain (/Users/serhiysolonko/Development/Projects/web-app/node_modules/systemjs-builder/lib/utils.js:220:13)
at getCanonicalName (/Users/serhiysolonko/Development/Projects/web-app/node_modules/systemjs-builder/lib/utils.js:145:19)
at /Users/serhiysolonko/Development/Projects/web-app/node_modules/systemjs-builder/lib/trace.js:471:36
The broccoli plugin was instantiated at:
at BundlePlugin.Plugin (/Users/serhiysolonko/Development/Projects/web-app/node_modules/broccoli-plugin/index.js:10:31)
at BundlePlugin.CachingWriter [as constructor] (/Users/serhiysolonko/Development/Projects/web-app/node_modules/broccoli-caching-writer/index.js:21:10)
at BundlePlugin (/Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/broccoli/angular-broccoli-bundle.js:10:36)
at Angular2App._getBundleTree (/Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/broccoli/angular2-app.js:421:22)
at Angular2App._buildTree (/Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/broccoli/angular2-app.js:159:21)
at new Angular2App (/Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/broccoli/angular2-app.js:53:23)
at module.exports (/Users/serhiysolonko/Development/Projects/web-app/angular-cli-build.js:6:10)
at Class.module.exports.Task.extend.setupBroccoliBuilder (/Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/models/builder.js:55:19)
at Class.module.exports.Task.extend.init (/Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/models/builder.js:89:10)
at new Class (/Users/serhiysolonko/Development/Projects/web-app/node_modules/core-object/core-object.js:18:12)
at Class.module.exports.Task.extend.run (/Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/tasks/build.js:15:19)
at /Users/serhiysolonko/Development/Projects/web-app/node_modules/angular-cli/lib/commands/build.js:32:24
at lib$rsvp$$internal$$tryCatch (/Users/serhiysolonko/Development/Projects/web-app/node_modules/rsvp/dist/rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (/Users/serhiysolonko/Development/Projects/web-app/node_modules/rsvp/dist/rsvp.js:1048:17)
at /Users/serhiysolonko/Development/Projects/web-app/node_modules/rsvp/dist/rsvp.js:331:11
at lib$rsvp$asap$$flush (/Users/serhiysolonko/Development/Projects/web-app/node_modules/rsvp/dist/rsvp.js:1198:9)
@SergeySolonko can you explain a bit what each option does, and how it affects the various parts of the build process?
I tried copy-pasting what you had, and I still get the error "Cannot find module '@web-app/anything'"
@NullVoxPopuli so tsconfig.json option responsible for compilation, system-config.js responsible for js loading.
this config works for standard folder configuration, at least first part. It should be something like this:
with system-config you're creating kind-a symlink to get access to specific module, with tsconfig.json you're saying which file you're expecting to get and that it should be compiled
now @web-app
basically it's a link to src/app/index.ts
module
@web-app/*
it's a link to rest of the files, e.g. @web-app/shared/index
I hope I've explained it clearly :)
'@web-app/*': {
format: 'cjs',
defaultExtension: 'js'
}
does nothing. The *
is not understood in SystemJS packages.
The path mapping is only used by TypeScript compiler to know which import corresponds to which modules. SystemJs operates on another level.
yes correct that was redundant, but still when you're trying to compile with _prod mode - it fails
I was able to get the system-config.js file to work correctly, but I added paths to the compilerOptions section of tsconfig.json and am unable to import, the compiler throws this error: Cannot find module '@app'
. I also looked at the schema for tsconfig.json and can't find anything about paths ...
https://www.typescriptlang.org/docs/handbook/compiler-options.html
Am I missing something? Here is my tsconfig.json...
{
"compileOnSave": false,
"compilerOptions": {
"paths": {
"@app" : ["//test.externalhost.com/app/index.ts"],
"@app/*": [
"//test.externalhost.com/app/*"
]
},
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"mapRoot": "@app",
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": false,
"outDir": "../dist/",
"rootDir": ".",
"sourceMap": true,
"target": "es5",
"inlineSources": true
},
"files": [
"main.ts",
"typings.d.ts"
]
}
I'm just starting with ng2, and it seemed very intuitive to me to try to use a full path. Why do people tend to use relative paths instead?
@tinchou, how do you use a full path? how do you ref your app root?
@tinchou Using relative paths can be easier when referencing a file in the same folder or a folder above. If you move a folder you don't have to fix all of the imports within that folder. But when the files are deeply nested and you are referencing something that is in the root of your source directory, I agree that full path tends to be simpler.
Also, the import system is related to ES2015 modules/TypeScript/System JS more than Angular 2 itself.
@NullVoxPopuli I haven't set it up, I'm just saying it didn't work by default.
@aciccarello true, but maybe having an alias to the root in the default template would help.
@tinchou that's what we are trying to get - to have a reference to very top folder (app folder). It works well for non-production build, for production - it fails. https://github.com/angular/angular-cli/issues/865#issuecomment-220969521
@SergeySolonko this is my +1 to having an alias to the app root by default with ng new
(that works in production too, of course :stuck_out_tongue:)
The following works for me for both ng build
and ng build -prod
.
$ ng --version
(node:5016) fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module, please update it to a more recent version.
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
angular-cli: 1.0.0-beta.5
node: 6.2.1
os: linux x64
tsconfig.json - Add the following paths
property to compilerOptions
"compilerOptions": {
...
"paths": {
"app/*": [
"./app/*"
]
}
}
Now the app directory should be able to be imported from as follows:
import { Logger } from 'app/shared/index';
Caveats
App specific barrels aren't able to be referenced by directory name when imported from an app-relative path regardless of whether a barrel definition exists in system-config.ts (not sure why).
import { Logger } from 'app/shared'; // won't work
import { Logger } from 'app/shared/index'; // will work
As an aside, I have no idea why the paths entry in tsconfig.json works when it should only be available in typescript@next (with the target milestone of 2.0) - https://github.com/Microsoft/TypeScript/pull/5728. As far as I can see both angular-cli and the default ng project scaffold use typescript 1.8.10
yeah, we definitely need aliases. webpack makes that pretty straightforward: https://webpack.github.io/docs/configuration.html#resolve-alias
obviously there's still the typescript compilation step in between which makes it a bit more tricky but the newly introduced paths
compiler option should be able to solve this.
i have a relatively small app and already have super ugly relative import
-paths. all the nice encapsulation through componentisation is basically destroyed because if you have relative paths everywhere, your app is basically a microlith with super high coupling.
Yeah, I've realized just recently that the import must work for the compile step and then for the dist version, where the files are loaded by SystemJs. The search paths for the typescript compiler seem to be kind of hardcoded, you can't tell it to use aliased paths like with SystemJs.
Anyone know how to do this using the webpack version?
A more broad issue that includes this one is being tracked in https://github.com/angular/angular-cli/issues/1465.
Settings paths in tsconfig as shown in https://github.com/angular/angular-cli/issues/865#issuecomment-225812336 should work. We've also removed barrels (they've become a bit unecessary with NgModules) so the problem @Blasz was experiencing with referencing them shouldn't be an overall thing.
@filipesilva Note that https://github.com/angular/angular-cli/issues/865#issuecomment-225812336 no longer works for me in the majority of cases with the webpack version. I can no longer import files from using the root-relative path when the file being imported contains other common imports (which it will in 95% of cases). It looks like a false positive circular-dependency related bug.
@Blasz is that a CLI or a typescript bug though?
@filipesilva I'm not quite sure but would lean towards CLI rather than typescript since the errors are being thrown by the webpack module resolution code rather than the typescript compiler. I'll try to investigate further and lodge a proper issue once I verify what the issue is exactly.
@Blasz appreciated!
@Blasz thanks a lot.
Had to write a little script to convert our existing import paths. Maybe someone can use it too: https://gist.github.com/dedeibel/65ebfc4ccb53a758952e4d812c832831 (perl)
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.
how do I set up a mapping for my app root to import? I'm trying to avoid doing:
and would like to do:
it is more intuitive, to specify an app-relative path, especially when refactoring (so you don't need to open the file tree, and count how many ../ you have...
I've tried adding mappings in my system-config.ts, but I haven't found anything to work.
doesn't work -- as in:
errors on build.