issues starting a node app with pm2 in production - pm2

I've got an instance of Apostrophe-CMS which I'm trying to deploy to production at the moment. Running sudo npm start works fine and the application boots. However, when I try to have the pm2 daemon run it I'm getting a symlink error:
Error: EEXIST: file already exists, symlink '/var/sites/hackday-2016-microsite/node_modules/apostrophe/lib/modules/apostrophe-assets/public' -> '/var/sites/hackday-2016-microsite/public/modules/apostrophe-assets'
hackday2016-28 at Error (native)
hackday2016-28 at Object.fs.symlinkSync (fs.js:1048:18)
hackday2016-28 at Object.self.linkAssetFolderOnUnix (/var/sites/hackday-2016-microsite/node_modules/apostrophe/lib/modules/apostrophe-assets/index.js:447:10)
hackday2016-28 at Object.self.linkAssetFolder (/var/sites/hackday-2016-microsite/node_modules/apostrophe/lib/modules/apostrophe-assets/index.js:424:14)
hackday2016-28 at /var/sites/hackday-2016-microsite/node_modules/apostrophe/lib/modules/apostrophe-assets/index.js:402:14
hackday2016-28 at /var/sites/hackday-2016-microsite/node_modules/lodash/index.js:3073:15
hackday2016-28 at baseForOwn (/var/sites/hackday-2016-microsite/node_modules/lodash/index.js:2046:14)
hackday2016-28 at /var/sites/hackday-2016-microsite/node_modules/lodash/index.js:3043:18
hackday2016-28 at Function.<anonymous> (/var/sites/hackday-2016-microsite/node_modules/lodash/index.js:3346:13)
hackday2016-28 at self.symlinkModules (/var/sites/hackday-2016-microsite/node_modules/apostrophe/lib/modules/apostrophe-assets/index.js:398:9)
hackday2016-28 at /var/sites/hackday-2016-microsite/node_modules/async/lib/async.js:718:13
hackday2016-28 at iterate (/var/sites/hackday-2016-microsite/node_modules/async/lib/async.js:262:13)
hackday2016-28 at async.forEachOfSeries.async.eachOfSeries (/var/sites/hackday-2016-microsite/node_modules/async/lib/async.js:281:9)
hackday2016-28 at _parallel (/var/sites/hackday-2016-microsite/node_modules/async/lib/async.js:717:9)
hackday2016-28 at Object.async.series (/var/sites/hackday-2016-microsite/node_modules/async/lib/async.js:739:9)
hackday2016-28 at Object.self.afterInit (/var/sites/hackday-2016-microsite/node_modules/apostrophe/lib/modules/apostrophe-assets/index.js:349:20)

I am pretty new to ApostropheCMS too and have been playing around for sometime. It looks like you have a symlink created to link the apostrophe-assets folder to a public folder? I don't understand the need to do that. AposCMS automatically picks up all the assets in the
node_modules/apostrophe/lib/modules/apostrophe-assets/public and
/var/sites/hackday-2016-microsite/public/modules/apostrophe-assets folders.
All you have to do is make sure that you are declaring the assets that you are adding for your project under
/var/sites/hackday-2016-microsite/lib/modules/apostrophe-pages/index.js
here is the code that I have under my file
module.exports = {
park: [{
slug: '/search',
type: 'apostrophe-search',
label: 'Search',
published: true
}],
types: [{
name: 'default',
label: 'Default'
},
{
name: 'home',
label: 'Home'
},
{
name: 'apostrophe-blog-page',
label: 'Blog'
}
],
//construct is one of the nunjucks functions that gets called when app.js starts
construct: function(self, options) {
//push assets to for use in front end - e.g. lib/modules/apostrophe-pages/public/js/site.js
self.pushAsset('script', 'site', { scene: 'always' });
self.pushAsset('script', 'jquery.easing', { scene: 'always' });
self.pushAsset('script', 'jquery.scrollTo', { scene: 'always' });
self.pushAsset('script', 'bootstrap', { scene: 'always' });
self.pushAsset('script', 'jquery.easing', { scene: 'always' });
self.pushAsset('script', 'jquery.matchHeight', { scene: 'always' });
self.pushAsset('script', 'jquery.easy-autocomplete', { scene: 'always' });
}
};
And for adding the css files, you can do that under
/var/sites/hackday-2016-microsite/public/modules/apostrophe-assets/public/css/site.less
my code in the file is:
#import 'utilities/_index.less';
#import 'typography/_index.less';
#import 'layout/_index.less';
#import 'templates/_index.less';
#import 'components/_index.less';
#import 'global/_index.less';
#import 'components/easy-autocomplete.less';
#import 'components/easy-autocomplete.themes.less';
// this is the place were we are adding the css syles so that they get automatically compiled
// and are minified and send out as one file
#import 'custom/bootstrap.less';
#import 'custom/font-awesome.less';
#import 'custom/jquery.autocomplete.less';
#import 'custom/simple-sidebar.less';
#import 'custom/style.less';
.apos-slideshow-item
{
h4
{
display: none;
}
}

Related

Adding additional module export from external file to webpack bundle

I have a project that requires an additional "config" file that I would like compiled into the final webpack bundle as an additional export of the bundled library.
The condition is that this config file, shouldn't need to be added to the entry file, but simply added an an additional export to the bundle.
I'm still relatively new to Webpack, but have been looking into how I might be able to accomplish this for a while now with no avail. Any help on getting into the right direction would be greatly appreciated!
Entry File (ts, using ts-loader):
export default class TestPlugin {
this.name: string;
constructor(name: string) {
this.name = name;
}
}
Plugin "config".
{
"name": "test plugin"
}
Plugin "loader" logic (separate project).
const plugin = require(path.resolve(pluginDirectory, fileName)
const config = plugin.config
const newPlugin = new plugin(config.name)
Webpack Config.
entry: ['./src/index.ts'],
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
output: {
filename: 'example.plugin.js',
path: path.resolve(__dirname, 'build'),
library: 'plugin',
libraryTarget: 'umd',
libraryExport: 'default',
globalObject: 'this',
},

It Shows value as undefined in webpage when i enter value from JSON file, Any idea?

It Shows value as undefined in webpage when i enter value from JSON file, Any idea?
JSON FILE:
[
{
"firstName":"1233232322",
"lastName":"ramakrishnan",
"email":"parthiramkrish#gmail.com",
"password":"secondmay1991",
"confirmPassword":"secondmay1991"
}
]
SPEC FILE:
'use strict';
browser.ignoreSynchronization = true;
var testdata1 = require('./testdata1.json');
describe("Test the inksoft.com create an account page", function () {
it("enter the account details", function () {
browser.get("https://qa.inksoft.com/EGT");
browser.ignoreSynchronization = true;
browser.sleep(15000);
element(by.xpath("//a[text()='Create Account']")).click();
browser.sleep(20000);
element(by.xpath("//input[#name='firstName']")).sendKeys( testdata1.firstName);
element(by.xpath("//input[#name='lastName']")).sendKeys( testdata1.lastName);
element(by.xpath("//input[#name='email']")).sendKeys( testdata1.email);
element(by.xpath("//input[#name='password']")).sendKeys( testdata1.password);
element(by.xpath("//input[#name='confirmPassword']")).sendKeys( testdata1.confirmassword);
element(by.xpath("//input[#type='submit']")).click();
});
});
CONF FILE:
exports.config = {
//The address of a running selenium server.
seleniumAddress: 'http://localhost:4444/wd/hub',
//Here we specify the name of the specs files.
framework: 'jasmine',
specs: ['inksoftdata.js'],
jasmineNodeOpts: {
showColors: true,
includeStackTrace: true,
defaultTimeoutInterval: 1440000
},
}
In testdata1.json file, all the data are stored as an array of objects. So to access the data from testdata1 variable you need to specify the array index like testdata1[0].firstName.

Trying to use request with ES6 + Webpack, but I am getting an error

I am currently trying to create a webapp with React, and I am trying to make a request to my server (with request). However, whenever I try to webpack the app I get an error. I am almost certain it has to do with request having to be labeled as an external library, but I can't get it to work. Can anybody help me?
Here is my webpack config.
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCSS = new ExtractTextPlugin();
module.exports = {
entry : [
'./js/index.js'
],
output : {
path : __dirname + '/lib/',
publicPath : 'http://localhost:8080',
filename : 'bundle.js'
},
plugins : [
new ExtractTextPlugin('app.css'),
new webpack.NoErrorsPlugin()
],
module : {
loaders : [
{
test : /\.js$/,
loaders : [
'babel'
],
exclude : /node_modules/
},
{
test : /\.(jpe?g|png|gif|svg)$/i,
loaders : [
'url?limit=8192',
'img'
]
},
{
test : /\.scss$/,
include : /styles/,
loader : extractCSS.extract([
'css',
'autoprefixer',
'sass'
])
}
]
},
resolve : {
extensions : ['', '.js', '.json']
},
externals : {
request : 'request'
}
};
and here is the error that I am getting
ERROR in ./js/services/comic
Module parse failed: /Users/matthew.pfister/IdeaProjects/web/js/services/comic Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import request from 'request';
|
| export default {
# ./js/creators/comic.js 11:21-49
Here is the file it is referencing
import request from 'request';
export default {
...
};
I dont think export default {...} is valid. try
var o = {...}
export default o
should work.
I just realized that the file that is throwing the error doesn't have the .js extension.
::facepalm:: everything is fixed.

Gulp favicon task

I am trying to make task for creating favicon images in GULP like this
var realFavicon = require ('gulp-real-favicon');
var fs = require('fs');
// File where the favicon markups are stored
var FAVICON_DATA_FILE = 'faviconData.json';
// Generate the icons. This task takes a few seconds to complete.
// You should run it at least once to create the icons. Then,
// you should run it whenever RealFaviconGenerator updates its
// package (see the check-for-favicon-update task below).
gulp.task('generate-favicon', function(done) {
realFavicon.generateFavicon({
masterPicture: 'TODO: Path to your master picture',
dest: 'TODO: Path to the directory where to store the icons',
iconsPath: '/',
design: {
ios: {
pictureAspect: 'noChange'
},
desktopBrowser: {},
windows: {
pictureAspect: 'noChange',
backgroundColor: '#da532c',
onConflict: 'override'
},
androidChrome: {
pictureAspect: 'shadow',
themeColor: '#ffffff',
manifest: {
name: 'MyApp',
display: 'browser',
orientation: 'notSet',
onConflict: 'override'
}
},
safariPinnedTab: {
pictureAspect: 'silhouette',
themeColor: '#5bbad5'
}
},
settings: {
scalingAlgorithm: 'Mitchell',
errorOnImageTooSmall: false
},
markupFile: FAVICON_DATA_FILE
}, function() {
done();
});
});
// Inject the favicon markups in your HTML pages. You should run
// this task whenever you modify a page. You can keep this task
// as is or refactor your existing HTML pipeline.
gulp.task('inject-favicon-markups', function() {
gulp.src([ 'TODO: List of the HTML files where to inject favicon markups' ])
.pipe(realFavicon.injectFaviconMarkups(JSON.parse(fs.readFileSync(FAVICON_DATA_FILE)).favicon.html_code))
.pipe(gulp.dest('TODO: Path to the directory where to store the HTML files'));
});
// Check for updates on RealFaviconGenerator (think: Apple has just
// released a new Touch icon along with the latest version of iOS).
// Run this task from time to time. Ideally, make it part of your
// continuous integration system.
gulp.task('check-for-favicon-update', function(done) {
var currentVersion = JSON.parse(fs.readFileSync(FAVICON_DATA_FILE)).version;
realFavicon.checkForUpdates(currentVersion, function(err) {
if (err) {
throw err;
}
});
});
Only problem I have is that i dont have faviconData.json can somebody share his, txanks
You should go back to Real Favicon Generator and follow the installation steps. Basically:
Replace the "TODO" in the generated code with actual paths.
Run gulp generate-favicon. This once-in-a-while task generates your icons and also the faviconData.json file you miss. For example this file contains the HTML markups that declare the icons.
Now you are ready to run gulp inject-favicon-markups whenever you deploy your site, update one of your pages, etc.
"favicons": {
"files": {
"src": "./dist/img/logo/favicon.png",
"dest": "./dist/img/favicons/",
"html": "./templates/misc/favicons.tpl.php",
"iconsPath": "./dist/img/favicons/",
"androidManifest": null,
"browserConfig": null,
"firefoxManifest": null,
"yandexManifest": null
},
"icons": {
"android": true,
"appleIcon": true,
"appleStartup": true,
"coast": true,
"favicons": true,
"firefox": true,
"opengraph": true,
"windows": true,
"yandex": true
},
"settings": {
"appName": "name",
"appDescription": "This is the app description",
"developer": null,
"developerURL": null,
"version": 1.0,
"background": null,
"index": null,
"url": null,
"silhouette": false,
"logging": true
},
"favicon_generation": null
},
maybe you can use this, you should change the settings of course :)

Making Grunt automatically remove files that are deleted

I use Grunt to automate converting my jade files. For that I use this script:
jade: {
compile: {
options: {
client: false,
pretty: true
},
files: [{
cwd: "_/components/jade",
src: "**/*.jade",
dest: "_/html",
expand: true,
ext: ".html"
}]
}
}
I also have this watch script running:
watch: {
jade: {
files: ['_/components/jade/**/*.jade'],
tasks: ['jade']
}
}
This works fine. However, when I delete a jade file, the html file remains. Is there a way to make grunt delete the corresponding html files when I delete a jade file?
If I understood you correctly, if you delete foo.jade you also want to delete foo.html correct? Here's an complete example using grunt-contrib-clean and grunt-contrib-watch:
You start by watching all the files with .jade extension with grunt watch. When a watched file is modified in some way, a watch event is emitted. If the event is deleted, we take the file path, change the extension to .html, set it as the src value of the clean:jade task and run the task.
module.exports = function(grunt) {
grunt.initConfig({
clean: {
jade: {
src: null
}
},
watch: {
jade: {
files: ['*.jade'],
options: {
spawn: false
}
},
}
});
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-contrib-clean");
grunt.event.on('watch', function(action, filepath) {
if (action === "deleted") {
var file = filepath.slice(0, -5) + ".html";
grunt.config.set('clean.jade.src', [file]);
grunt.task.run("clean:jade");
}
});
};
For more information, see Using the watch event # grunt-contrib-watch. Note that spawn option must be false
If you need to dynamically modify your config, the spawn option must be disabled to keep the watch running under the same context.
You need grunt-contrib-clean. But this code clear all files of same type and make grunt slowly and require a specific config for every task. So often just use clean single time when grunt start:
module.exports = function (grunt){
grunt.initConfig({
pckg: grunt.file.readJSON('package.json'),
clean: { // Grun-contrib-clean tasks
jade: ["dist/*.html"],
all: ["dist"]
},
jade: {
dist: {
files: [{
expand: true,
cwd: 'src/templates',
src: ['**/*.jade'],
dest: 'dist',
filter: 'isFile',
ext: '.html'
}]
}
},
watch: {
jade: {
files: ['src/templates/**/*.jade'],
tasks: ['clean:jade','jade']
},
}
});
require('load-grunt-tasks')(grunt);
grunt.registerTask('default', ['clean:all', 'jade', 'watch']);
};