I am trying to write a gulp task that does a few things
Install the Bower dependencies
Concat those dependencies into one file in the order of the dependencies
I was hoping to do this without having to specify the paths to those dependencies. I know there is the command bower list --paths but I am unsure of if it is possible to tie it together.
Any thoughts?
Edit
So I am trying to use the gulp-bower-files and I am getting an eaccess error and its not generating the concatenated file.
gulpfile.js
var gulp = require('gulp');
var bower = require('bower');
var concat = require('gulp-concat');
var bower_files = require('gulp-bower-files');
gulp.task("libs", function(){
bower_files()
.pipe(concat('./libs.js'))
.pipe(gulp.dest("/"));
});
bower.json
{
"name": "ember-boilerplate",
"version": "0.0.0",
"dependencies": {
"ember": "1.6.0-beta.1",
"ember-data": "1.0.0-beta.7"
}
}
and I keep coming across this error
events.js:72
throw er; // Unhandled 'error' event
^
Error: EACCES, open '/libs.js'
Use main-bower-files
It grabs all production (main) files of your Bower packages defined in your project's bower.json and use them as your gulp src for your task.
integrate it in your gulpfile:
var mainBowerFiles = require('main-bower-files');
I made this task that grabs all production files, filters css/js/fonts and outputs them in the public folder in their respective subfolders (css/js/fonts).
Here's an example:
var gulp = require('gulp');
// define plug-ins
var flatten = require('gulp-flatten');
var gulpFilter = require('gulp-filter'); // 4.0.0+
var uglify = require('gulp-uglify');
var minifycss = require('gulp-minify-css');
var rename = require('gulp-rename');
var mainBowerFiles = require('main-bower-files');
// Define paths variables
var dest_path = 'www';
// grab libraries files from bower_components, minify and push in /public
gulp.task('publish-components', function() {
var jsFilter = gulpFilter('**/*.js');
var cssFilter = gulpFilter('**/*.css');
var fontFilter = gulpFilter(['**/*.eot', '**/*.woff', '**/*.svg', '**/*.ttf']);
return gulp.src(mainBowerFiles())
// grab vendor js files from bower_components, minify and push in /public
.pipe(jsFilter)
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(uglify())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(jsFilter.restore())
// grab vendor css files from bower_components, minify and push in /public
.pipe(cssFilter)
.pipe(gulp.dest(dest_path + '/css'))
.pipe(minifycss())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/css'))
.pipe(cssFilter.restore())
// grab vendor font files from bower_components and push in /public
.pipe(fontFilter)
.pipe(flatten())
.pipe(gulp.dest(dest_path + '/fonts'));
});
I was attempting to run the listed gulpfile and ran into a couple errors. First gulpFilter.restore is not a function, and secondly if you plan on restoring the filtered files you need to pass {restore: true} when you define your filters.
Like so:
// gulpfile.js
var mainBowerFiles = require('main-bower-files');
var gulp = require('gulp');
// define plug-ins
var flatten = require('gulp-flatten'),
gulpFilter = require('gulp-filter'),
uglify = require('gulp-uglify'),
minifycss = require('gulp-minify-css'),
rename = require('gulp-rename'),
mainBowerFiles = require('main-bower-files');
// Define paths variables
var dest_path = 'www';
// grab libraries files from bower_components, minify and push in /public
gulp.task('publish-components', function() {
var jsFilter = gulpFilter('*.js', {restore: true}),
cssFilter = gulpFilter('*.css', {restore: true}),
fontFilter = gulpFilter(['*.eot', '*.woff', '*.svg', '*.ttf'], {restore: true});
return gulp.src(mainBowerFiles())
// grab vendor js files from bower_components, minify and push in /public
.pipe(jsFilter)
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(uglify())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(jsFilter.restore)
// grab vendor css files from bower_components, minify and push in /public
.pipe(cssFilter)
.pipe(gulp.dest(dest_path + '/css'))
.pipe(minifycss())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/css'))
.pipe(cssFilter.restore)
// grab vendor font files from bower_components and push in /public
.pipe(fontFilter)
.pipe(flatten())
.pipe(gulp.dest(dest_path + '/fonts'));
});
After the changes mentioned it ran perfectly. :)
Related
Can someone tell me what I'm doing wrong in my gulp.js file to allow for the user to hit save and it update my .css file from the .sass file change?
If I manually hit Run under my Task it will work
Can anyone see any issues?
/// <binding AfterBuild='compile' ProjectOpened='default' />
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
// Requires the gulp-sass plugin
var sass = require('gulp-sass');
gulp.task("sass", function (done) {
return gulp.src('Content/styles/**/*.scss', '!Content/styles/vendor')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write())
.pipe(gulp.dest('Content/styles/'));
});
function watch() {
gulp.watch('Content/styles/**/*.scss', gulp.series("sass"));
}
gulp.task("compile", gulp.series("sass"));
gulp.task('default', watch);
I have a Meteor application deployed with nginx.
I try to upload images from the application to save the images on the server. When I'm in localhost, I save my images in the myapp/public/uploads folder. But, when I deploy, this folder become myapp/bundle/programs/web.browser/app/uploads. So, when I upload an image, it saved in a new folder in myapp/public/uploads. But so, I can't access to it. When I'm in localhost I access to my images like that : localhost:3000/uploads/myImage.png but when I do myAdress/uploads/myImage.png I access to the myapp/bundle/programs/web.browser/app/uploads folder and not the one where the images are saved (myapp/public/uploads).
This is my code to save images :
Meteor.startup(function () {
UploadServer.init({
tmpDir: process.env.PWD + '/app/uploads',
uploadDir: process.env.PWD + '/app/uploads',
checkCreateDirectories: true,
uploadUrl: '/upload',
// *** For renaming files on server
getFileName: function(file, formData) {
//CurrentUserId is a variable passed from publications.js
var name = file.name;
name = name.replace(/\s/g, '');
return currentTileId + "_" + name;
},
finished: function(fileInfo, formFields) {
var name = fileInfo.name;
name = name.replace(/\s/g, '');
insertionImages(name, currentTileId, docId);
},
});
});
So, do you know how can I do to save and access to my images when the application is deployed ? Maybe save the image in the myapp/bundle/programs/web.browser/app/uploads folder or access to the myapp/public/uploads folder with an url.
This is what we do.
Use an external dir for uploads, say, /var/uploads. Keeping the uploads in public folder makes the meteor app to reload in the dev environment, on any file upload.
Now, at local, use Meteor to serve these files at a certain url. In production, use nginx to serve the same at the same url.
For Development
1) Symlink your upload dir to a hidden folder in public.
eg:
ln -s /var/uploads /path/to/public/.#static
2) Serve the public hidden folder via Meteor by using:
The url /static will server the folder public/.#static by using the following code on the server. Ref: How to prevent Meteor from watching files?
var fs = require('fs'), mime = require('mime');
WebApp.rawConnectHandlers.use(function(req, res, next) {
var data, filePath, re, type;
re = /^\/static\/(.*)$/.exec(req.url);
if (re !== null) {
filePath = process.env.PWD + '/public/.#static/' + re[1];
try {
stats = fs.lstatSync(filePath);
if (stats.isFile()) {
type = mime.lookup(filePath);
data = fs.readFileSync(filePath, data);
res.writeHead(200, {
'Content-Type': type
});
res.write(data);
res.end();
}
}
catch (e) {
// console.error(filePath, "not found", e); // eslint-disable-line no-console
next();
}
}
else {
next();
}
});
For production
1) Use nginx for serving the upload dir
server {
...
location /static/ {
root /var/uploads;
}
...
}
That's it. /static will server the content of your uploads dir i.e. /var/uploads
I am trying to create a yeoman generator where I have to copy from templatePath to destinationPath some files and folders, but I would want to have some of this files with a variable that yeoman could change by one of the user's inputs.
like: "<%=name%>-plugin.php" -> "hello-plugin.php"
I saw some references that this can be done but I can't find how.
I am doing right now:
//Copy the configuration files
app: function () {
this.fs.copyTpl(
this.templatePath('**'),
this.destinationPath(),
{
name: this.props.pluginName,
name_function: this.props.pluginName.replace('-', '_'),
name_class: this.props.className,
description: this.props.pluginDescription
}
);
}
I thought that with that code my <%=name%> would magically changed on copyTpl but it doesn't work
I've just found the solution:
Use this.registerTransformStream(); to pipe all files through some node.js script.
var rename = require("gulp-rename");
//other dependecies...
module.exports = yeoman.Base.extend({
//some other things generator do...
writing: function() {
var THAT = this;
this.registerTransformStream(rename(function(path) {
path.basename = path.basename.replace(/(666replacethat666)/g, THAT.props.appName);
path.dirname = path.dirname.replace(/(666replacethat666)/g, THAT.props.appName);
}));
this.fs.copyTpl(
this.templatePath(),
this.destinationPath(), {
appName: this.props.appName
});
}
});
I'm using here gulp-rename to change file names to something else.
Assuming that this.props.appName == "myFirstApp", this:
666replacethat666-controller.html
will change its name to
myFirstApp-controller.html
Following #piotrek answer, I made a function to replace all props with some pattern (like ejs does) -> $$[your prop name]$$. warning: ES6 inside
var rename = require("gulp-rename");
//other dependecies...
module.exports = yeoman.Base.extend({
//some other things generator do...
writing: function() {
this.registerTransformStream(rename((path) => {
for (let prop in this.props) {
let regexp = new RegExp('\\$\\$' + prop + '\\$\\$', 'g')
path.basename = path.basename.replace(regexp, this.props[prop]);
path.dirname = path.dirname.replace(regexp, this.props[prop]);
}
}));
this.fs.copyTpl(
this.templatePath(),
this.destinationPath(), {
appName: this.props.appName
});
}
});
Example:
Let's assume you have this.props.appname = MyApp and this.props.AnotherProps = Test and you want to rename file or folder.
Name your file or folder MyFile$$appname$$.js -> MyFileMyApp.js
Name your file or folder $$appname$$.js -> MyApp.js
Name your file or folder $$AnotherProps$$.js -> Test.js
This is not possible anymore. The feature was bloated and was removed at some point in 2015.
For now, just rename the file:
this.fs.copy('name.js', 'new-name.js')
Lets say I have a project that uses bower, grunt, bowerify(with shim) and since I love Jest so much I want to test with that. How in the world do I get jest to see my browserify shim modules when it runs tests. I use grunt, to kick off the npm test command.
Here is my package.json file.
"browser": {
"jquery": "./bower_components/jquery/dist/jquery.js",
"foundation": "./bower_components/foundation/js/foundation/foundation.js",
"fastclick": "./bower_components/fastclick/lib/fastclick.js",
"greensock-tm": "./bower_components/gsap/src/uncompressed/TweenMax.js",
"greensock-css": "./bower_components/gsap/src/uncompressed/plugins/CSSPlugin.js",
"greensock-time": "./bower_components/gsap/src/uncompressed/TimelineMax.js",
"scrollmagic": "./bower_components/ScrollMagic/js/jquery.scrollmagic.js",
"handlebars": "./bower_components/handlebars/handlebars.runtime.js"
},
"browserify-shim": {
"jquery": "$",
"greensock-css": "CSSPlugin",
"fastclick": "FastClick",
"greensock-tm": "TweenMax",
"greensock-time": "TimelineMax",
"scrollmagic": "ScrollMagic",
"foundation": "foundation",
"handlebars": "Handlebars"
},
"browserify": {
"transform": [
"browserify-shim"
]
},
Right now I almost have this worked out by doing this in my grunt file before I run the test.
grunt.registerTask("shimBowerForTests",function(){
var readJson = require('read-package-json');
var fs = require('fs');
var remapify = require('remapify');
readJson('./package.json', console.error, false, function (er, data) {
if (er) {
throw "There was an error reading the file";
}
var packages = data.browser;
var browserify = require('browserify');
for (var key in packages){
var b = browserify();
var wstream = fs.createWriteStream("devjs/test/modules/"+key+'.js');
b.add(packages[key]);
b.bundle().pipe(wstream);
}
});
});
and.
exec: {
jestTest: {
command: 'cp -r devjs/modules devjs/test/modules && npm test'
}
}
The problem is that using browserify so combine everything for the browser works great with my setup and I can require my shimmed modules like this.
require('jquery') //example but in the jest cli the test fail because they can find the module unless I somehow prefix it with ./, like so require('./jquery')
I'm guessing that the problem is that you've only installed your shimmed modules with bower. If you want them to work in node/jest, you'll have to install them with npm as well. Then just make sure Jest isn't mocking anything in the node_modules directory, and it should find all the required modules in there as long as the names match up.
Your Jest config in package.json should look like:
"jest": {
"unmockedModulePathPatterns": [
"./node_modules"
]
}
And then just download all the dependencies.
npm install jquery --save-dev
UPDATE
Instead of using my below solution you should opt for using Karma,karma browserify. I have converted the below solution into using karma and it is working much much better.
----------------------OLD ANSWER
What I actually did to solve this was, used the Jest source preprocessor to rewrite the require statement to look for a module in a certain directory in my /tests/ folder that I have created using grunt. The Folder contains the files listed in my browserify-shim, browser section of the package.json file.
EDIT: Here is how I shim bower, I made this script in the Gruntfile.js that puts all the bower modules and any commonjs modules that I need into an accessible directory.
grunt.registerTask("shimBowerForTests", function() {
var readJson = require('read-package-json');
var fs = require('fs');
readJson('./package.json', console.error, false, function(er, data) {
if (er) {
throw "There was an error reading the file";
}
var packages = data.browser;
var shim = data['browserify-shim'];
var browserify = require('browserify');
var exclude = ["jquery.maskedinput", "jquery"];
for (var key in packages) {
var b = browserify();
var wstream = fs.createWriteStream("devjs/test/modules/" + key + '.js');
if (shim[key] !== undefined && exclude.indexOf(key) === -1) {
b.add(packages[key]);
b.bundle().pipe(wstream);
} else {
var rstream = fs.createReadStream(packages[key]);
rstream.pipe(wstream);
}
}
});
});
Then in the Jest pre processor file I do this.
module.exports = {
process: function(src, path) {
var src2= src.replace(/require\([\"\']([^\.\'\"]+)[\"\']\)/g, "require(\'../modules/$1\')");
src2= src2.replace(/jest\.dontMock\([\"\']([^\.\'\"]+)[\"\']\)/g, "jest.dontMock(\'../modules/$1\')");
return src2;
}
};
I am working with the yo meanjs boilerplate from here :yo meanjs.
I know I can create my own module using $ yo meanjs:angular-module <module-name> .
Is it possible to install and inject into my controller ng-flow using yo from the command line?
Something like : $ yo meanjs:ng-flow <module-name>
In the documentation it states found here meanjs modules: So unless there are any better suggestions I might try this route.
To add third-party modules use the public/config.js file where we added an array property called applicationModuleVendorDependencies. When you add a new third-party module you should add it to this array so the main module can load it as a depenedency.
'use strict';
// Init the application configuration module for AngularJS application
var ApplicationConfiguration = (function() {
// Init module configuration options
var applicationModuleName = 'theconnect';
var applicationModuleVendorDependencies = ['ngResource', 'ngCookies', 'ngAnimate', 'ngTouch', 'ngSanitize', 'ui.router', 'ui.bootstrap', 'ui.utils'];
// Add a new vertical module
var registerModule = function(moduleName, dependencies) {
// Create angular module
angular.module(moduleName, dependencies || []);
// Add the module to the AngularJS configuration file
angular.module(applicationModuleName).requires.push(moduleName);
};
return {
applicationModuleName: applicationModuleName,
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
registerModule: registerModule
};
})();
After adding module via cmd line using :
bower install "ng-flow#~2" --save
grunt bower-install
I added it as as dependency to public/config.js :
var applicationModuleVendorDependencies = ['ngResource', 'ngCookies', 'ngAnimate', 'ngTouch', 'ngSanitize', 'ui.router', 'ui.bootstrap', 'ui.utils','flow'];
then added the module path to the all the JS files under the /config/env directory.
module.exports = {
db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/theconnect',
assets: {
lib: {
css: [
'public/lib/bootstrap/dist/css/bootstrap.min.css',
'public/lib/bootstrap/dist/css/bootstrap-theme.min.css',
],
js: [
'public/lib/angular/angular.min.js',
'public/lib/angular-resource/angular-resource.js',
'public/lib/angular-cookies/angular-cookies.js',
'public/lib/angular-animate/angular-animate.js',
'public/lib/angular-touch/angular-touch.js',
'public/lib/angular-sanitize/angular-sanitize.js',
'public/lib/angular-ui-router/release/angular-ui-router.min.js',
'public/lib/angular-ui-utils/ui-utils.min.js',
'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
'public/lib/ng-flow/dist/ng-flow.js'
]
},
css: 'public/dist/application.min.css',
js: 'public/dist/application.min.js'
},
......
...
}
Fabii's answer is helpful. To add to it...
I had to make 2 entries in the "all.js" file Fabii mentioned (which is located at /config/env/all.js
'public/lib/flow.js/dist/flow.min.js',
'public/lib/ng-flow/dist/ng-flow.js'