Urigo / angular2-meteor

Angular 2.0 and Meteor - the perfect stack
http://www.angular-meteor.com/
298 stars 61 forks source link

[Meteor 1.3-beta.16] npm client-side lib import scenario #171

Closed MilosStanic closed 8 years ago

MilosStanic commented 8 years ago

After days and days and days of unsuccessful tries to repackage any Angular2 package for Atmosphere, I decided to give Meteor 1.3 a shot.

So, I upgraded my meteor installation meteor update --release 1.3-beta.16

(I didn't upgrade angular2-meteor to 0.5.0-beta.something because I didn't know how to)

So I created a package.json file and put ng2-material into my dependencies. Then I ran npm install and it did create a node_modules directory in my project and installed the ng2-material and all its dependencies.

Then in code I do import like this

import {MATERIAL_DIRECTIVES} from 'ng2-material/all';

And my Visual Studio Code recognizes that the actual library exists somewhere in the path. But after the app is served, it tries to load the library from http://localhost:3000/ng2-material/all and it serves a html file with empty body tag and all other scripts and css files listed in the head tag.

Finally, after recognizing the fact that it is searching for the script where it cannot be found, I sought alternative way to import the directives via require, so here is how it works:

var MD = require('ng2-material/all');
var MATERIAL_DIRECTIVES = MD.MATERIAL_DIRECTIVES;

(this is because multiple objects are exported from ng2-material/all and packed into a single object, so I had to manually extract what I need)

This is really a bad way to do this, but the only way I could currently find. I read on meteor forums that this import should have been fixed, and they recommend doing meteor add modules, or even better meteor add ecmascript, but in our case ecmascript package conflicts with barbatus:angular2.

Now, I'm not sure if the barbatus:angular2 is the one that improperly handles the imports. This is worth, investigating, I think.

Thanks for your attention.

barbatus commented 8 years ago

I don't understand the point here. You are using NPM, so why do you need barbatus:angular2? It's an Atmosphere package , supposed to be used with Meteor 1.2. There is Angular2 NPM package, besides that, if you spend 1 minute of your time and read updated README, you'll find out that TypeScript can still be used with Meteor 1.3 - you just need to install angular2-compilers package.

MilosStanic commented 8 years ago

Hi @barbatus I don't know why I need barbatus2:angular2. I tried so many combinations, that I lost track why and what I tried.

I did spend several minutes reading README's, and besides we don't know if I read it before or after it was updated. The README was not always in accordance with reality, and you know it. I usually spend days and hours trying and testing things before I decide posting an issue.

I have noticed you lashing out on users asking questions before. We are all busy people, and I understand you are super busy, but simply tone down your language, please. If you are nervous, better don't answer. I've spent hundreds of hours reading issues and discussions on Github, and I don't remember finding anyone similarly harsh as you are in answering questions here.

Thanks for all your hard work. I have immense respect for your knowledge and effort, but simply this is not the way to communicate.

Thanks again.

derekkite commented 8 years ago

I found that I needed to start a fresh meteor project, get things basically working, then moving my code over. Otherwise there are too many variables to deal with and almost impossible to sort out. I'm now back to finding my own things that don't work using the meteor 1.3rc updates and angular2-meteor.

barbatus commented 8 years ago

@MilosStanic Sorry if I offended you. "Customer support" is certainly not my best skill, I'll though try to improve. I see the problem here is in that we still have very few contributors and yet rather low number of users. When these numbers continue to rise, this problem will dissolve by itself since there will be bunch of people who are ready to help and understand all the tricks of the project.

barbatus commented 8 years ago

So let's try ng2-material with TypeScript and Angular2-Meteor NPM (installed from the repo), if it's ok - consider closing this issue.

MilosStanic commented 8 years ago

@barbatus No problem. As I said, we all have stress at work. I will try to contribute myself as much as I can. I will try ng2-material and fresh install today, as it failed before. Will report here and close the issue. Thanks again for your hard work.

MilosStanic commented 8 years ago

I just managed to tweak ng2-material into running with my project. my package.json looks like this:

{
  "name": "mcalc",
  "version": "0.0.1",
  "description": "Metals prices calculator",
  "author": "MilosStanic",
  "dependencies": {
    "angular2": "2.0.0-beta.9",
    "es6-promise": "3.0.2",
    "es6-shim": "^0.33.3",
    "meteor-node-stubs": "~0.2.0",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.2",
    "zone.js": "0.5.15",
    "ng2-material": "0.2.11",
    "angular2-materialize": "*",
    "angular2-meteor": "git+https://github.com/Urigo/angular2-meteor.git",
    "angular2-meteor-auto-bootstrap": "git+https://github.com/Urigo/angular2-meteor-auto-bootstrap.git"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "license": "ISC"
}

Note the older version of ng2-material because the new version requires Angular2-beta.11, and the old one works with beta.9 which is required by angular2-meteor packages.

Peculiarity is that in this setup I had to change paths to my imports, so for example, instead of import {something} from '/client/componentdir/something'; I had to do import {something} from '../componentdir/something';

barbatus commented 8 years ago

@MilosStanic What would be if you install just angular2-meteor and angular2-meteor-auto-bootstrap? All other peer dependencies (like angular2, zone.js etc) should be installed along. As for changing to relative urls, it's because of moduleResolution set to NodeJS style, where absolute paths are resolved in node_modules. Next version of the tutorial will strive to explain these nuances.

MilosStanic commented 8 years ago

Strangely, I'm getting messages like: client/sheet/sheet.ts (1, 32): Module '"angular2/core"' resolves to a non-module entity and cannot be imported using this construct.

And the app is not really working, but no messages in browser console. Simply doesn't quite work. It renders (without material design), but it doesn't work.

@barbatus your last message came in just as I was typing above... let me test your proposals.

MilosStanic commented 8 years ago

@barbatus it works when I only install just angular2-meteor and angular2-meteor-auto-bootstrap as you suggested.

However, the messages as quoted in my above post remained, until I replaced import of angular/core with:

'../../node_modules/angular2/core'

Still, app not behaving like it was before. I have to see what is wrong. No errors in browser or meteor console.

MilosStanic commented 8 years ago

Note: templateUrl imports still work with 'old' url notation of 'client/component/component.html'

barbatus commented 8 years ago

it should work with just 'import {..} from angular2/core'. If you have jsconfig.json then try to check how it works w/o it. If not, then I'll need a repo to check, if you want me to help.

Devidian commented 8 years ago

i think i got it running in my test project now using angular beta9 instead of 11, i will now try to get this working for my real project too.

By the way:

npm install https://github.com/Urigo/angular2-meteor --save
npm install https://github.com/Urigo/angular2-meteor-auto-bootstrap --save

both are not running under my windows test enviroment because mv (move) is not available ofcourse

MilosStanic commented 8 years ago

@barbatus thanks for all your help today. I didn't get it working with regular import {Component} from 'angular2/core' even when I removed jsconfig.json and tsconfig.json. Something is wrong in my app setup, I just have to dig and find it. It works normally on a blank app, as we tested on the other issue. On my app even Visual Studio code marks imports from angular2/core as irregular, so something definitely wrong with the setup. I will find out what. Thanks again for all your help.

MilosStanic commented 8 years ago

@Devidian are you actually able to see material design components in your test project?

Devidian commented 8 years ago

yes and no, it seems only css is running so far :( (i just copied css from node_modules to public folder and imported them in my main.less) everything else seems not to work as it should. But wait, i think i missed to ... hmm yeha there was noimport {MATERIAL_DIRECTIVES} from 'ng2-material/all'; now its working

MilosStanic commented 8 years ago

@Devidian not working for me at all... didn't try to move css and less files, but nothing works. I get a regular button when I put <button md-button>something</button>

MilosStanic commented 8 years ago

@Devidian how do you exactly import css to your main.less? It seems it works now (forgot to add directives: [MATERIAL_DIRECTIVES]) :) but lacks css for button.

Devidian commented 8 years ago

first i tried to import them from node_modules but got an error on frontend because he searched the files domain.com/node_modules... instead of importing them (what i thought it would do) so i created a folder public/media/css/ng2-material/ and put font.css and ng2-material.css + map files and fonts in there. in my less files i just added:

@import "/media/css/ng2-material/font.css";
@import "/media/css/ng2-material/ng2-material.css";

to the beginning of the file

Devidian commented 8 years ago

i have a crazy error on my real project. i cant import anything even if the file is in the same directory and i try to

import './test';

it keeps telling me the file is missing. I just copied the layout from my working test project, any ideas ? Maybe i should go home for today :D

barbatus commented 8 years ago

what version of 1.3 are you using?

Devidian commented 8 years ago

rc.4 currently as in my test-project, its exactly the same setup (it should be) i will try to create a new meteor project with --release tomorrow, maybe there was something going wrong moving to npm from athmosphere packages. It was a bit late at work... :)

Devidian commented 8 years ago

ok i figured out my pathings problem, i just missed to export something in the import chain. On serverside i just imported ../imports/startup/server/start which imported ../../api/users/server/publications in wich only this content was:

Meteor.publish("userData", function () {
  if (this.userId) {
    return Meteor.users.find({_id: this.userId},
                             {fields: {'isRoot': 1}});
  } else {
    this.ready();
  }
});

when i added this line:

export var x;

he found the path and was correctly booting

MilosStanic commented 8 years ago

Okay, so what is the conclusion here? Is the ng2-material package bad (which I doubt, because nobody complains at their repo), or is Meteor 1.3 having problems with importing? I also managed to make things work by moving css files, but not to /public, but to /client/assets/ folder. However, Chrome reports problems parsing fonts and source maps:

Failed to parse SourceMap: http://localhost:3000/client/assets/css/font.css.map
Failed to parse SourceMap: http://localhost:3000/client/assets/css/ng2-material.css.map
Failed to decode downloaded font: http://localhost:3000/client/assets/css/MaterialIcons-Regular.woff2
(index):1 OTS parsing error: invalid version tag
(index):1 Failed to decode downloaded font: http://localhost:3000/client/assets/css/MaterialIcons-Regular.woff
(index):1 OTS parsing error: invalid version tag
(index):1 Failed to decode downloaded font: http://localhost:3000/client/assets/css/MaterialIcons-Regular.ttf
(index):1 OTS parsing error: invalid version tag

The font problem appears when I try to make use of any icon.

barbatus commented 8 years ago

@Devidian right now if a file doesn't export anything it's just added to the output barely, which means your publications anyways should be executed and be available ultimately. The reason behind that is TypeScript internal modules (e.g., declare module Foo {}), the feature that was asked by some users. It's actually hard to decide here what's better. So what would you prefer better by default: still import files wholly (e.g, import './foo') or let some files (that don't export) to execute by themselves (but you actually can control execution using internal modules)? I tend to think now that mixing is probably not good.

MilosStanic commented 8 years ago

Okay, finally, here's the proper recipe for adding scss resources from node_modules to your project in the proper Meteor 1.3 way:

  1. Install a sass compiler

npm install --save node-sass

  1. Edit your package.json and add into your scripts section (if you don't have the section create it), the build:css script:
"scripts": {    
    "build:css": "node-sass --include-path node_modules client/assets/css/main.scss client/assets/css/bundle.css --output client/assets/css"
  }

Format of node-sass script params is node-sass [options] <input.scss> [output.css]

In our case, we tell the node-sass to look into node_modules dir to find scss files, we use client/assets/css/main.scss as input file, and client/assets/css/bundle.css as output file and we set client/assets/css as output dir.

  1. create your client/assets/css/main.scss as per instructions at ng2-material:
$md-font-url: "node_modules/ng2-material/dist/";
@import "node_modules/ng2-material/dist/font.css";
@import "node_modules/ng2-material/dist/font.scss";
@import "node_modules/ng2-material/source/all.scss";

(I had to include all files by full extensions, because node-sass was confused which files to compile)

  1. compile the scss files by running:

npm run build:css

That's it. I still have those odd messages about compiling fonts in Chrome when using icons. I will report if I solve this.

Devidian commented 8 years ago

@barbatus Well, maybe my english is not that good to get the point on imports, but in my opinion it should be possible to import files that just do stuff, so i can just comment the import statements on need, they shouldn't execute themselves on the other hand. Thats why i choose to convert my project to the new directory structure recommended by meteor 1.3 - so i can have a better control what is really imported - but i also want to seperate my code. For now i just exported var x on every file without an export and it seems to do it's thing - ists just a bit hacky :)

barbatus commented 8 years ago

@Devidian TypeScript has its own modules (http://www.typescriptlang.org/Handbook#modules). There was discussion on this topic in some other place. The point there was one can still have modularity if a file w/o direct (ES6) exports is added barely to the output. But again, I tend to think that mixing ES6 and TypeScript modules is not the best practice.

Devidian commented 8 years ago

@barbatus ok i see, i'm very new to TypeScript, started a little more than a week ago, so i'm not into all specific things right now. Thanks for the link ;)

MilosStanic commented 8 years ago

Importing assets from npm packages is an issue for Meteor 1.3, and unfortunately won't be resolved before 1.3.1

You can track it here https://github.com/fourseven/meteor-scss/issues/165 and here https://github.com/meteor/meteor/issues/6037

I am closing this issue, as I feel everything has been resolved as much as it can. Thank you all.

shotleybuilder commented 8 years ago

@barbatus "All other peer dependencies (like angular2, zone.js etc) should be installed along." Meteor1.2 didn't require ng2 to be installed prior to ng2-meteor. ng2 was installed along as you suggest.

But, when I simply npm install angular2-meteor --save I get UNMET PEER DEPENDENCY angular2@2.0.0-beta.12

UPDATE: ng2 has to be installed also. See here: https://www.npmjs.com/package/angular2-meteor-auto-bootstrap

Which means it would be nice to have a package.json that installs a working framework. Here's my non-working effort:

    "angular2": "2.0.0-beta.12",
    "systemjs": "0.19.24",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.2",
    "zone.js": "0.6.6",
    "angular2-meteor": "0.5.2",
    "angular2-meteor-auto-bootstrap": "0.5.1",
    "@angular2-material/core": "^2.0.0-alpha.1",
    "sax": "1.1.5",
    "xml2js": ">=0.4.16" 

Everything installs, my typings files look correct, and this project previously was working with the Atmosphere package of ng2-meteor with Meteor 1.3 (not the npm). But importing angular meets with the same error to MilosStanic: Module '"angular2/core"' resolves to a non-module entity and cannot be imported using this construct. But, import of "angular2-meteor-auto-bootstrap" is fine!! My next step is to vary my package.json with a clean project. I can't really make much progress without being able to import ng2/core :-)

My clean install package.json

{
  "dependencies": {
    "angular2": "2.0.0-beta.12",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.2",
    "zone.js": "^0.6.6",
    "angular2-meteor": "0.5.2",
    "angular2-meteor-auto-bootstrap": "0.5.1",
    "@angular2-material/core": "^2.0.0-alpha.1"
  }
}

And my simple app.ts:

import {Component} from 'angular2/core';
import {bootstrap} from 'angular2-meteor-auto-bootstrap';
@Component({
    selector: 'app',
    template:`
    <h2>My App</h2>
    `
})
class myapp {
}
bootstrap(myapp);

I have a simple index.html (<body><app></app></body>). Everything boots, no errors in the console, but importing angular2/core isn't working app.ts:1 Uncaught ReferenceError: require is not defined

I will see if typings make a difference

barbatus commented 8 years ago

@shotleybuilder see this comment https://github.com/Urigo/angular2-meteor/issues/171#issuecomment-199808977 by MilosStatic , he had wrong setup and ultimately made it work. As to peer dependencies, if you are installing new version of Angular2-Meteor (which relies on say Angular2 beta-12) and have previous Angular2 version beta-9 installed already, running npm install angular2-meteor should install Angular2-beta12 (as it happens to me) but will complain about unmet dependencies like es6-shim. The only way to fix is to update manually like npm install es6-shim@^0.35.0 or add them to your package.json like you did. If you didn't have all previous versions installed, then running npm install angular2meteor would be just enough. Angular2 is still in beta, so we currently require specific version of Angular2 (set in peerDependencies) to guarantee that users have version that we tested.

shotleybuilder commented 8 years ago

Okay, so I created a clean app but forgot to meteor update --release 1.3-rc.13 Now I'm hit with a new error on my clean app install: reflect-metadata shim is required when using class decorators reflect-metadata is in my list of node-modules. Further investigation needed!

shotleybuilder commented 8 years ago

Fixed and working. I had to bump up the version of angular2-compiler: meteor add angular2-compilers@0.5.4 That's the clean project, now to get my real project working!

barbatus commented 8 years ago

@shotleybuilder it should work with just meteor add angular2-compilers. if you have some prev version of angular2-compilers installed, then meteor update angular2-compilers should be enough to update.

shotleybuilder commented 8 years ago

This error: app.ts:1 Uncaught ReferenceError: require is not defined Was caused by missing ecmascript package. This was removed in the initial Meteor1.2 install of my project following the advice in the ng2-meteor tutorial "As of Meteor 1.2, Meteor supports ES6 by default. In order to avoid conflicts between TypeScript and Meteor ECMAScript package, you'll need to remove it". Well, it appears it's needed in Meteor1.3?? Or perhaps there is a config that allows this package to be safety removed?