After upgrading to 0.9.0.1 it would seem that CoffeeScript packages have two problems:
The exports from package.js don't seem to be exported.
The source files don't seem to be compiled.
package.js:
Package.describe({
summary: "sunburn"
});
Package.on_use(function (api, where) {
api.add_files(['lib/sunburn.coffee'], 'server');
api.export && api.export('Stinger', 'server');
});
Package.on_test(function (api) {
});
sunburn.coffee:
Stinger = -> "stinger here"
This is a local package. Both 'meteor add sunburn' and 'meteor remove sunburn' work fine. If sunburn.coffee is modified the server restarts. However, 'Stinger' is undefined when used from the server-side code. Somewhat more interestingly, if sunburn.coffee is modified to include syntax errors, the server will happily restart and no error will be reported. This is what leads me to believe that the CoffeeScript files aren't even being compiled. Or, at least, not being fully "wired up".
Code similar to this worked in the pre 0.9 version.
One last note: if the sunburn.coffee is changed to be a normal js file, 'Stinger' rewritten as normal javascript, and the file path updated in package.js, the above works fine.
Thanks :-)
You need to specify that your package actually depends on coffeescript to make the compilation happen :
api.use("coffeescript","client");
Previously, only having your app depending on build plugins (less, coffeescript, etc...) was OK but apparently now you have to specify that you use them inside packages as well.
Unrelated, but you should also specify a version in your Package.describe, and testing for the existence of api.export is unrelevant because I hope nobody is using Meteor < 0.6.5 anymore.
Related
I'm using skipper to receive the files, sharp to resize (and save) and fs unlink to remove the old image. But I got a very weird error this time that concerns me a lot:
error: ** Grunt :: An error occurred. **
error:
Aborted due to warnings.
Running "copy:dev" (copy) task
Warning: Unable to read "assets/images/users/c8e303ca-1036-4f52-88c7-fda7e01b6bba.jpg" file (Error code: ENOENT).
error: Looks like a Grunt error occurred--
error: Please fix it, then restart Sails to continue running tasks (e.g. watching for changes in assets)
error: Or if you're stuck, check out the troubleshooting tips below.
error: Troubleshooting tips:
error:
error: *-> Are "grunt" and related grunt task modules installed locally? Run npm install if you're not sure.
error:
error: *-> You might have a malformed LESS, SASS, CoffeeScript file, etc.
error:
error: *-> Or maybe you don't have permissions to access the .tmp directory?
error: e.g., (edited for privacy)/sails/.tmp ?
error:
error: If you think this might be the case, try running:
error: sudo chown -R 1000 (edited for privacy)/sails/.tmp
Grunt stopped running and to have that in production is a big NoNo... I believe that this is caused because of concurrency with fs.unlinkSync(fname). The error is also intermittent and very hard to reproduce in some machines (IO ops/sec maybe?).
I have the following controller action:
var id = 1; // for example
req.file('avatar').upload({
dirname: require('path').resolve(sails.config.appPath, 'assets/images')
}, function(err, files){
var avatar = files.pop();
//file name operations here. output is defined as the path + id + filetype
//...
sharp(avatar.fd)
.resize(800, 800)
.toFile(output, (err, info)=>{
if(err){
res.badRequest();
} else {
fs.unlinkSync(avatar.fd);
res.ok();
}
});
});
Now I've been thinking about a few solutions:
Output the new image directly to .temp
Unlink when files exists on .tmp. Explanation: Grunt already copied the old file so removing it would be safe!
But I don't know if this is some spaghetti code or even if a better solution exists.
EDIT: My solution was, as proposed by arbuthnott, wrap a controller like this:
get : function(req, res){
var filepath = req.path.slice(1,req.path.length);
//remove '/' root identifier. path.resolve() could be used
if(fs.existsSync(path.resolve(filepath))){
return res.sendfile(filepath);
} else {
return res.notFound();
}
}
I think you are on the right track about the error. You are making some rapid changes to in the assets folder. If I read your code right:
Add an image with user-generated filename to assets/images (ex cat.jpg)
Copy/resize the file to an id filename in assets/images (ex abc123.jpg)
Delete the original upload (cat.jpg)
(I don't know the details of sharp, there may be more under the hood there)
If sails is running in dev mode, then Grunt will be trying to watch the whole assets/ folder, and copy all the changes to .tmp/public/. It's easy to imagine Grunt may register a change, but when it gets around to copying the added file (assets/images/cat.jpg) it is already gone.
I have two suggestions for the solution:
One:
Like you suggested, upload your original to the .tmp folder (maybe even a custom subfolder of .tmp). Still place your sized copy into /assets/images/, and it will be copied to /.tmp/public/ where it can be accessed as an asset by the running app. But Grunt will ignore the quick add-then-delete in the .tmp folder.
Two:
Do a bit of general thinking about both what you want to include in version control, and what Grunt tasks you want to be running in production. Note that if you use sails lift --prod then Grunt watch is turned off by default, and this error would not even occur. Generally, I don't feel like we want Grunt to do too much in production, it is more of a development shortcut. Specifically, Grunt watch can use a lot of resources on a production server.
The note about version control is just that you probably want some of the contents of assets/images/ to be in version control (images used by the site, etc), but maybe not in the case of user-uploaded avatars. Make sure you have a way to differentiate these contents (subdirectories or whatever). Then they can be easily .git-ignore'd or whatever is appropriate.
Hope this helps, good luck!
What are the constraints that Meteor is trying to resolve when it loads the packages at startup? Is it all related to versioning or is it actually looking at the code that you load with ap.use() in packages.js?
I am getting this error when I try to start up my project. I have a super-simple package file that I created with the meter create --package command. I put all of my files that make up the package into the directory that it created and moved that directory to .meteor/packages. I'm just trying to create a local package for now. Here's the contents of package.js in that directory:
Package.describe({
name: 'ammap-meteor',
summary: 'mapping library packaged for meteor ',
version: '1.0.0',
});
Package.onUse(function(api) {
api.versionsFrom('METEOR#0.9.0');
api.addFiles('ammap.js');
api.addFiles('ammap_amcharts_extension.js');
});
Package.onTest(function(api) {
api.use('tinytest');
api.use('ammap-meteor');
api.addFiles('ammap-meteor-tests.js');
});
My ammap-meteor-tests.js file is blank for the moment but it exists. Would that make a difference? And I assume you just omit the git: property from Package.onUse() for a local package, is that right?
OK, I was able to get past that error with the publish command:
meteor publish --create
So I did not succeed in making a local package (still not clear on that) but at least I can get the package to load now.
I have trouble setting up a simple iron:router example: (docs, sample app)
meteor create testapp
cd testapp
home.html:
<template name="Home">
<h1>Welcome</h1>
home
</template>
router.js:
Router.route('/', function () {
this.render('Home'); // Also tried 'home'
});
Starting the server:
meteor
Then I get (client side):
Exception from Tracker recompute function: Error: Couldn't find a template named "/" or "". Are you sure you defined it?
at null._render (http://localhost:3000/packages/iron_dynamic-template.js?32038885cb1dad7957291ffebfffcb7f8cd57d20:239:17)
at doRender (http://localhost:3000/packages/blaze.js?88aac5d3c26b7576ac55bb3afc5324f465757709:1853:25)
...
What am I doing wrong ?
Note: I get the exact same error if I clone the example application (basic.html and basic.js).
meteor list
autopublish 1.0.1 Publish the entire database to all clients
insecure 1.0.1 Allow all database writes by default
iron:router 0.9.4 Routing specifically designed for Meteor
meteor-platform 1.1.2 Include a standard set of Meteor packages in your app
Also:
meteor --version
Meteor 0.9.4 <- Why all standard packages and meteor platform are > 1.0 and this is 0.9.4 ?
Currently, there are two versions of iron:router.
iron:router#0.9.4 is the one added by default when you type meteor add iron:router, this version is the latest in the "legacy" branch of iron:router that came up more than one year ago, it's the one that everyone is probably still using, although they should definitely update to...
iron:router#1.0.0-preX with X = 4 as of 20/10/2014, which is a complete rewrite of the package intended to be backward compatible, but introducing a new, nicer and polished API. This version will likely be set as default when meteor hits 1.0.0 later this year. The problem is that github page of iron:router shows this particular branch (1.0.0-pre4) along with examples that people believe are usable with 0.9.4.
This means that you are most likely using the wrong version of iron router, remove it with meteor remove iron:router and meteor add iron:router#1.0.0-pre4 instead.
Recommended reading to learn about the latest iron:router syntax :
http://eventedmind.github.io/iron-router/
Sometimes the guide is not completely up-to-date with the pre-release version, if you want to keep up with the latest stuff take a look at github issues.
My current project is at https://github.com/jimmack1963/localPackages.git.
I am trying to get this code to work:
console.log("You pressed the button, " + MyName);
where MyName comes from a package called simple, that is JUST LOCAL. Per 6.5, am exporting via
Package.on_use(function (api, where) {
api.add_files(['constant.js'], 'client');
//below added per possible suggestion from Nathan, had no effect.
api.use('constant.js', 'client');
if (api.export)
api.export('MyName');
});
Am trying to factor my code out to local packages. This is not about publishing packages, but about using local ones, which is referred to in many places. My package is simply trying to publish a string, MyName. But the project wants none of it. "MyName is not defined."
I copy the technique in 'Discover Meteor,' but it doesn't work for me, and I try other things. Have had a lot of success in Meteor in general.
This spec seems to be changing. I get the 6.5 export requirement, but easily find contradictory advise about the base project's need to add that project in smart.json (not the one in the package). Most references don't list that as a requirement at all.
I've tried
{
"packages": {
"simple" : {
"path": "packages/simple"
}
}
}
and putting it into git and trying from a different project:
{
"packages": {
"simple" : {
"git": "https://github.com/jimmack1963/localPackages.git"
}
}
}
For the latter, pleasingly, the installer was smart enough to burrow down and extract the package itself, ignoring the project wrapping it in the git project. Nice! So, I have the same problem when I install the package directly from git, still not published to the world.
Ubuntu 13.04
Meteorite version 0.6.11
Meteor Release 0.6.5.1
I had the same issue after migrating to 0.6.5 -
You only get 'exported' variables from packages you explicitly "use"; Packages "use" other packages by calling .use inside Package.on_use, projects "use" packages by adding them to .meteor/packages
Additionally, it seems to be quite picky about exporting variables, and wont currently export ones preceded with this.
in ~/.meteor/package/ folder all package.js files has only this:
// This file is included for compatibility with the Meteor 0.6.4 package downloader.
and nothing more.
Where is the package.js code?
Thanks!
The package system has changed.
You will find the auto-generated file you're refering to under:
/packages/name_of_your_package/.build/
As for where the actual 'package.js' file is, it's under
/packages/name_of_your_package/
As per the source code that's building these files for you:
// Pre-linker versions of Meteor expect all packages in the warehouse to
// contain a file called "package.js"; they use this as part of deciding
// whether or not they need to download a new package. Because packages
// are downloaded by the *existing* version of the tools, we need to
// include this file until we're comfortable breaking "meteor update" from
// 0.6.4. (Specifically, warehouse.packageExistsInWarehouse used to check
// to see if package.js exists instead of just looking for the package
// directory.)
// XXX Remove this once we can.
builder.write("package.js", {
data: new Buffer(
("// This file is included for compatibility with the Meteor " +
"0.6.4 package downloader.\n"),
"utf8")
});
I hope this helps!