modifying the bodyParser size in sails.js without having to modify the sails library sourcefile - sails.js

I modified the bodyParser option size for posting huge strings through input forms in sails.
I did it the following way:
I went to: node_modules/sails/lib/express/index.js
And then I replaced the default bodyParser :
bodyParser = sails.config.express.bodyParser();
by
bodyParser = sails.config.express.bodyParser({limit: 8248242});
I works, but I suppose there must be an easier way to do it via parameters or something...
I tried to create an express.js file in the config folder like in https://gist.github.com/mikermcneil/8249181
but it does not seem to recognise the express module...
Any advice about what would be the best way to change the bodyParser size limit via some kind of parameter?
Cheers!

Thanks Scott! I don't know how this voting system works, but I am grateful for your help!! I had not realised that express was not explicitely added to the package.json and that sails has its own internal separate express distribution. I added express in package.json, and an express.js as follow in the config folder:
module.exports.express = {
express: {
bodyParser: function () {
return require('express').bodyParser({ limit: 8248242 })
}
}
};
and it now works after npm install... Thanks a lot!

The expected awswer won't work with Sails v10.
Here's the fix that worked for me.
You need to install the body-parser NPM
npm install body-parser
then add
bodyParser: function () { return require('body-parser')({ limit: 8248242 }) }
into config/http.js

This now works for me in Sails 1.2.3; specifically, using the example bodyParser in the default config/http.js:
...
bodyParser: (function _configureBodyParser(){
var skipper = require('skipper');
var middlewareFn = skipper({
// strict: true,
limit: '10mb',
});
return middlewareFn;
})(),
...

Related

How do I disable babel minification when not in production?

I am using babelify and babili for JS minification, via gulp:
// Now run the watchifys function for this bundle
watchifysForBundle[jsBundle]
// Note: we don't use any babel presets - instead we just write code in what evergreen browsers support
.transform(babelify, {
presets: ['babel-preset-babili'],
ignore: ['buffer']
})
However I can't seem to find how to pass the options to check NODE_ENV and disable babeli when not in production. The babelify docs don't seem to help, even with this common use case.
How can I disable babelify minification when not in production?
Babili is deprecated and has been renamed to babel-minify, so you should be using that instead.
npm install babel-preset-minify --save-dev
To disable the minification in development you simply don't use the babel-preset-minify (or babel-preset-babili for that matter). As you're using Gulp you can use everything Node.js has to offer to decide which presets you want to include, which means that you can check process.env.NODE_ENV and decide whether you want to include the minify preset.
watchifysForBundle[jsBundle]
.transform(babelify, {
presets: process.env.NODE_ENV === 'production' ? ['minify'] : [],
ignore: ['buffer']
})
An alternative would be to use Babel's env option (not to confuse with babel-preset-env), which uses the configuration that matches the value of BABEL_ENV or NODE_ENV if no BABEL_ENV was defined. This approach is shown in babel-preset-minify - Usage.
{
"env": {
"production": {
"presets": ["minify"]
}
}
}
The env option is not really recommended and mainly exists because .babelrc is JSON and there is no good way to define conditional configurations. This will change in Babel 7 which allows a .babelrc.js config where you have the full power of Node.js and that means you could do the same thing as with Gulp.
To avoid minification, don't use uglify
gulp.task('build:js', function(){
return browserify(
'test.js'
)
.transform('babelify',{
presets: ['#babel/preset-env']
})
.bundle()
.pipe(source('test.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('destpath'));
});
Instead try--- adding option- compact:false, global:true in babelify
gulp.task('build:js', function(){
return browserify(
'test.js'
)
.transform('babelify',{
presets: ['#babel/preset-env'],
compact: false,
global: true
})
.bundle()
.pipe(source('test.js'))
.pipe(buffer())
.pipe(gulp.dest('destpath'));
});

How can I build mongoose in the browser with webpack?

Our app uses mongoose (v4.6.5) in the browser(http://mongoosejs.com/docs/browser.html) but I have recently switched over to using webpack (v2.1.0-beta.27) and webpack-dev-server (for development: v(2.1.0-beta.11) to run our builds and it's having trouble parsing mongoose.
When it tries, it gets this error:
WARNING in ./~/mongoose/lib/drivers/index.js
8:11 Critical dependency: the request of a dependency is an expression
I went to that file and saw that it tries to import a binary file if window is undefined:
/*!
* ignore
*/
var driver;
if (typeof window === 'undefined') {
driver = require(global.MONGOOSE_DRIVER_PATH || './node-mongodb-native');
} else {
driver = require('./browser');
}
/*!
* ignore
*/
module.exports = driver;
I'm guessing mongoose in the browser does NOT want to read from the binary file which is the point of this check. The problem is that window doesn't exist at the point of compilation since it's being compiled by webpack, so it also attempts to statically analyze this binary file.
I tried adding this to the mongoose file to prevent webpack from proceeding down mongoose's server-side dependency graph:
/*!
* ignore
*/
var driver;
if (typeof window === 'undefined' && process.env.BUILD_ENV !== 'browser') {
driver = require(global.MONGOOSE_DRIVER_PATH || './node-mongodb-native');
} else {
driver = require('./browser');
}
/*!
* ignore
*/
module.exports = driver;
I then run my webpack build with env BUILD_ENV=browser webpack-dev-server but it doesn't work, I'm guessing because webpack doesn't actually execute your code but statically analyzes it.
I saw this PR on mongoose as well but it doesn't seem to have fixed my issue: https://github.com/Automattic/mongoose/pull/4512/files.
My question then is how can I use mongoose in the browser (with webpack) without having it read from the binary file?

How can I use my webpack's html-loader imports in Jest tests?

I am just getting started with the Jest test framework and while straight up unit tests work fine, I am having massive issues testing any component that in its module (ES module via babel+webpack) requires a HTML file.
Here is an example:
import './errorHandler.scss';
import template from './errorHandler.tmpl';
class ErrorHandler {
...
I am loading the component specific SCSS file which I have set in Jest's package.json config to return an empty object but when Jest tries to run the import template from './errorHandler.tmpl'; line it breaks saying:
/Users/jannis/Sites/my-app/src/scripts/errorHandler/errorHandler.tmpl.html:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<div class="overlay--top">
^
SyntaxError: Unexpected token <
at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:284:10)
My Jest config from package.json is as follows:
"jest": {
"setupTestFrameworkScriptFile": "<rootDir>/test/setupFile.js",
"moduleDirectories": ["node_modules"],
"moduleFileExtensions": ["js", "json", "html", "scss"],
"moduleNameMapper": {
"^.+\\.scss$": "<rootDir>/test/styleMock.js"
}
}
It seems that the webpack html-loader is not working correctly with Jest but I can't find any solution on how to fix this.
Does anyone know how I can make these html-loader imports work in my tests? They load my lodash template markup and i'd rather not have these at times massive HTML chunks in my .js file so i can omit the import template from x part.
PS: This is not a react project, just plain webpack, babel, es6.
I encountered this specific problem recently and creating your own transform preprocesser will solve it. This was my set up:
package.json
"jest": {
"moduleFileExtensions": [
"js",
"html"
],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.html$": "<rootDir>/test/utils/htmlLoader.js"
}
}
NOTE: babel-jest is normally included by default, but if you specify a custom transform preprocessor, you seem to have to include it manually.
test/utils/htmlLoader.js:
const htmlLoader = require('html-loader');
module.exports = {
process(src, filename, config, options) {
return htmlLoader(src);
}
}
A bit late to the party, but wanted to add that there is also this html-loader-jest npm package out there to do this if you wanted to go that route.
Once you npm install it you will add it to your jest configuration with
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.html?$": "html-loader-jest"
}
For Jest > 28.x.x with html-loader:
Create a custom transformer as documented here.
jest/html-loader.js
const htmlLoader = require("html-loader");
module.exports = {
process(sourceText) {
return {
code: `module.exports = ${htmlLoader(sourceText)};`,
};
},
};
Add it to your jest config.
jest.config.js
...
// A map from regular expressions to paths to transformers
transform: {
"^.+\\.html$": "<rootDir>/jest/html-loader.js",
},
...
It will fix the error : Invalid return value: process() or/and processAsync() method of code transformer found at "<PATH>" should return an object or a Promise resolving to an object.
Maybe your own preprocessor file will be the solution:
ScriptPreprocessor
Custom-preprocessors
scriptpreprocessor: The path to a module that provides a synchronous function from pre-processing source files. For example, if you wanted to be able to use a new language feature in your modules or tests that isn't yet supported by node (like, for example, ES6 classes), you might plug in one of many transpilers that compile ES6 to ES5 here.
I created my own preprocessor when I had a problems with my tests after added transform-decorators-legacy to my webpack module loaders.
html-loader-jest doesn't work for me. My workaround for this:
"transform": {
'\\.(html)$': '<rootDir>/htmlTemplateMock.html'
}
htmlTemplateMock.html is empty file
For Jest 28+ you can use jest-html-loader to make Jest work with code that requires HTML files.
npm install --save-dev jest-html-loader
In your jest config, add it as a transformer for .HTML files:
"transform": {
"^.+\\.html?$": "jest-html-loader"
},

How do I run only certain tests in karma?

I have karma config set up correctly, config file, running in the background, just great. As soon as I change and save a file, it reruns the tests.... all 750 of the unit tests. I want to be able to run just a few. Short of manually hacking the config file or commenting out hundreds of tests across many files, is there any easy way to do it?
E.g. when running command line server tests using say mocha, I just use regexp: mocha -g 'only tests that I want'. Makes it much easier to debug and quickly check.
So now I feel foolish. mocha supports a very narrow version of regexp matching.
This runs all tests
describe('all tests',function(){
describe('first tests',function(){
});
describe('second tests',function(){
});
});
This runs just 'first tests'
describe('all tests',function(){
describe.only('first tests',function(){
});
describe('second tests',function(){
});
});
You can also do it.only()
I should have noticed that. Sigh.
You can do that at karma startup time unfortunately, not at runtime.
If you want to change it dynamically you have to put some more effort.
Say you want to focus on a specific set/suite of tests from the beginning, on the karma-mocha plugin page there's this snippet of code to do what you want:
module.exports = function(config) {
config.set({
// karma configuration here
...
// this is a mocha configuration object
client: {
// The pattern string will be passed to mocha
args: ['--grep', '<pattern>'],
...
}
});
};
In order to make the <pattern> parametric you have to wrap the configuration file in a Configurator that will listen CLI and customize the karma configuration for you.
Have a look to this SO answer to know how to setup a very simple Configurator.
I have same question and this is my workround by a little change on karma.conf.js.
In fact, take an argument from command line and modify the pattern in "files".
I use minimist to parse the argument list.
In config file:
/* Begin */
var minimist = require('minimist');
var argv = minimist(process.argv);
var testBase="test/unit";
var testExt=".spec.js";
var unitTestPattern = testBase+'/**/*'+testExt;
if ("test" in argv){
unitTestPattern = testBase+"/"+argv["test"]+testExt;
}
/* End */
module.exports = function(config){
config.set({
//....
files : [
//....
unitTestPattern, //place here
// 'test/unit/**/*.spec.js', //replace this
//....
],
//....
});
};
run in command prompt:
karma start test/karma.conf.js --single-run --test #TEST_CASE_FILE#
a nice extension that can help here is karma-jasmine-html-reporter-livereload
https://www.npmjs.com/package/karma-jasmine-html-reporter-livereload
or karma-jasmine-html-reporter https://www.npmjs.com/package/karma-jasmine-html-reporter?__hstc=72727564.86845f057bb4d741f59d578059e30644.1443860954685.1453095135802.1453138187458.37&__hssc=72727564.1.1453138187458&__hsfp=2285154675
It creates a debug page in which you can run each test individually. very useful for large projects!
1) In your karma.conf.js get the params from the terminal:
var files = (process.env.npm_config_single_file) ? process.env.npm_config_single_file : 'test/test_index.js';
2) In order to run a single test you will need to set an option object with all your configuration (Without files and preprocessors):
var option = {
webpack: {
// webpack configuration
},
// more configuration......
};
3) Set your files path and preprocessors:
option.files = [
{pattern: files, watch: false}
];
option.preprocessors = {};
option.preprocessors[files] = [ 'webpack', 'sourcemap' ];
// call config.set function
config.set(option);
4) Run in the terminal:
npm test --single_file=**/my-specific-file-spec.js
For more information check this PR:
https://github.com/webpack/karma-webpack/pull/178
There are different ways to do it.
Use --grep option. The disadvantage of this is that all the tests are preprocessed before running the specific test suite.
Use .only method. Disadvantage same as no. 1. Using both 1 and 2 method my node process used to crash often saying out of memory.
Limit the files options for processing. This is super fast.
Limit preprocessing to certain folder like Unit or Integration folder.
For this I have used custom cli option --only and in the karma config
const modules = config.only;
and in the the files pattern
files: typeof modules === 'string ? '[`tests/**/${module}/**/*.(test|spec).js`]: 'tests/**/*.(test|spec).js'
Advantage: Developers can run only certain tests when they make a small change way faster by limiting in the preprocessing phase.
You can also use combination of no.3 and no.1 or 2.

sails.js Is it possible to set process.env variables from application?

I am trying to use npm module fb to use facebook api. The config file is located in the module and here is the snapshot of the same
var config = { };
// should end in /
config.rootUrl = process.env.ROOT_URL || 'http://localhost:3000/';
config.facebook = {
appId: process.env.FACEBOOK_APPID || '130243393813697',
appSecret: process.env.FACEBOOK_APPSECRET || 'c82696768ae4ad8b63db874cb64eb558',
appNamespace: process.env.FACEBOOK_APPNAMESPACE || 'nodescrumptious',
redirectUri: process.env.FACEBOOK_REDIRECTURI || config.rootUrl + 'login/callback'
};
module.exports = config;
I don't wish to change the config file of the module since node_modules folder is kept in the gitignore list. For configuring the module to use my app's appId and appSecret, I need to set the process.env variables FACEBOOK_APPID and FACEBOOK_APPSECRET
I understand that it can be done while calling the sails lift but is it by any means possible to set these values inside the app so that I only have to call
sails lift
without any of those variables and those should be set automatically ? Or what is the best way to achieve what I am trying to do here ?
You should set the environment-variables outside of your App.
Instead of sails lift you could also use node app.js. With that you can define environment-variables for your node-application with:
$> FOO='bar' node app.js
In your case:
$> FACEBOOK_APPID='232322a22' FACEBOOK_APPSECRET='mysecrete' node app.js
If you want to set this vars in your app (I wouldn't suggest that!) you could set them before including your npm-module. For example in your config/bootstrap.js:
module.exports.bootstrap = function(cb) {
process.env.FACEBOOK_APPID = "myvar";
process.env.FACEBOOK_APPSECRET = "mysecrete";
sails.facebook = require("yourmodule");
cb();
};
Here is a good link for setting environment variables when "Production", "Staging" and "Development" in Sails feels fragmented.
Here is a quick video tutorial which simply explains how to create environment variables in node.js
Step1:
Install the package dotenv as dependency
$ npm install dotenv --save
Step2:
Then require dotenv in app.js and load the .env file
var dotenv = require('dotenv');
dotenv.load();
Step3:
Create a .env file in the root folder (ie. at the same document level as app.js file)
Step4:
Add your environment variables
S3_KEY=enfiownqefniqofewqofnieqwvewlk
S3_SECRET=123456789
Now you can access those environment variables anywhere in the app (probably in some config/ files):
return {
key: process.env.S3_KEY,
secret: process.env.S3_SECRET,
region: 's3-eu-west-1',
bucket: 'myBucket',
s3params: {
ACL: 'public-read'
}
}
Credit goes to Noah Bass for providing this tutorial.