Gulp require alias - gulp

I am looking for a safe way of doing require aliases using gulp.
The idea is similar to what webpack offers with resolve alias.
For example, I put on my source code something like require('#plugin/utils') and it is translated to something of my choice, like require('$/plugins/longer/namespace/utils'). You probably have noticed that it does not match to any actual file path, and that is intentional (they are tiddlywiki files if anyone is interested).
The best thing I found is gulp-replace, but that relies on strings replacements at worst and regular expressions at best.
Ideally I would want something more reliable, something that is AST aware,so I'm sure that I never replace the wrong string (for example, a template string).
I am also using babel, so if there is a babel plugin that I can use I will also be happy about that.
As a last resort I may try to write some babel plugin or a gulp plugin using esprima, but esprima is not up to modern JS standard (doesn't parse object spread) and I would prefer creating another tool.
Thanks in advance

Finally I found a babel module (babel-plugin-module-resolver) that I can integrate with gulp, and with some extra configuration magic with eslint.
So, this is what I added to my gulp pipeline (simplified)
const babelCfg = {
plugins: [[
require.resolve('babel-plugin-module-resolver'),
{
root: [ `${pluginSrc}/**` ],
alias: { '#plugin': `$:/plugins/${pluginNamespace}` },
loglevel: 'silent',
}
]],
};
return gulp
.src(`${pluginSrc}/**/*.js`)
.pipe(babel(babelCfg))
.pipe(gulp.dest(outPath.dist));
That converts all the references to require('#plugin/xxxx') with the proper path.
With some extra configuration you can even make eslint warn you about bad path resolutions.
You need to configure it differently because eslint needs the real path, while the output files needs a special namespace. After installing both eslint-import-resolver-babel-module and eslint-plugin-import this is what you should add to your eslint config to make it work:
plugins:
- import
env:
node: true
browser: true
settings:
import/resolver:
babel-module:
root: ./src/**
alias:
"#plugin": ./src/the/real/path
rules:
import/no-unresolved: [2, { commonjs: true }]

Related

Composer autoload file before loading dependencies

One of the vendor packages I'm requiring exposes a function by autoloading it:
{
...
"autoload": {
...
"files": [
"functions.php"
]
}
}
Unfortunately it lacks multilingual support.
As I really like the function's fluent definition and I already have a drop-in multilingual alternative., I would like to use my drop-in replacement instead while still using the same function name. Luckily the package has implemented a function_exists() check, so I just need to declare my function before the package is autoloaded.
I know I could just reference a require before requiring Composer's autoloader, but are there any composer.json alternatives to accomplish this? Is there any way I can tell Composer to load a specific file first, before anything else?
More specifically I'm looking to override Laravel's unlocalized now() function to a localizable version. Since this question is also applicable to other applications and/or dependencies I kept my question quite generic.

Babel cli preset config

Due to some certain reason I don't wish to use .babelrc file even though I'm well aware of the fact that I'm supposed to follow the rules. Anyways, for the run time I'm using the following code
require('babel-register')({
babelrc: false,
presets: [
'stage-0',
['env', {
targets: {
node: 'current'
}
}]
],
plugins: [
'transform-async-to-generator',
'syntax-async-functions'
]
});
require('../server/core');
Now I need the same config to be executed from shell. E.g.
babel config --out-dir
Thanks for your help
There is currently no way to pass plugin/preset options via CLI arguments. https://github.com/babel/babel/issues/4161 so if you don't wish to use a .babelrc then there's no easy way to get args in via the CLI command.
Given that, your next best bet would be to use something like gulp-babel to put together your own build pipeline with programmatic arguments like babel-register has.

How can I turn off ESLint's no-restricted-syntax rule just for ForOfStatement?

I am using ESLint for my ES6 program, with the AirBNB rule-set. For good and adequate reasons, I am using the for...of construction in my code, but ESLint objects to it, issuing a no-restricted-syntax error.
The documentation at http://eslint.org/docs/rules/no-restricted-syntax explains how I can specify in my .eslint file the set of syntax-tree nodes that it objects to: for example, if all I dislike is the with statement, I can use:
"no-restricted-syntax": ["warn", "WithStatement"]
But I don't want to specify a whole set of unapproved constructions, I just want to say that I consider one such construction OK. Something conceptually similar to
ESlint.rules['no-restricted-syntax'].removeEntry('ForOfStatement');
Is there a way to do this in the ESLint file? Or, failing that, is there at least a way to get it to tell me what its current no-restricted-syntax configuration is, so I can manually remove ForOfStatement from it?
Check existing config
Based on the current master branch, eslint-config-airbnb currently disables four syntax forms:
ForInStatement
ForOfStatement
LabeledStatement
WithStatement
You can verify this or see if there are any differences by using ESLint's --print-config CLI flag:
$ eslint --print-config file.js
ESLint will print out the config it would use to lint file.js, and you can find the config for the no-restricted-syntax rule there.
Override no-restricted-syntax
If you want to override Airbnb's preset, you can do so in the rules section of your .eslintrc.json file:
{
"rules": {
"no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"]
}
}
There's no way to configure the rule to use the no-restricted-syntax config inherited from Airbnb's preset excepting only a single syntax form.
Add the below lines of code to restrict this error in your application in .eslintrc.js file
module.exports = {
extends: ['airbnb-base', 'plugin:prettier/recommended'],
plugins: ['no-only-tests'],
rules: {
'no-only-tests/no-only-tests': 2,
"no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"]
},
};

Gulp-Webpack Loaders returning loader source code?

Newbie. I'm setting up gulp-webpack to run in a Gulp task, and I'm starting simple by processing a test "less" file. I npm-installed gulp-webpack, webpack, and also the webpack loaders less-loader, css-loader, and style-loader. For some reason, my output css file isn't ... instead it's a js file containing what appears to be source code for a loader itself. Do I need to require the webpack loaders within the webpack config file?
My gulpfile.js:
var gulpwebpack = require('gulp-webpack');
gulp.task('go2',function(){
return gulp.src('src/homesMenuAngular/css/*.less')
.pipe(gulpwebpack( require('./webpack.config.js') ))
.pipe(gulp.dest('builds/homesMenuAngular/css'));
});
My webpack.config.js:
// no require statements
module.exports = {
module: {
loaders: [
{
test: /\.less$/,
loader: "style!css!less"
}
]
}
};
So, most experienced webpackers are probably rolling their eyes, because yes, webpack does output javascript that injects all the other resources into the page. I was thinking "let's use a webpack loader to convert less to css" and "let's use gulp" to automate the whole build process but I hadn't taken a deep enough dive into how webpack works specifically that it bundles everything into 1 or more js files.

Module.exports vs plain json for config files

I see multiple ways to create config files in Node.js. One uses module.exports in js file, one just use plain json object.
// config1.js
module.exports = {
config_1: "value 1",
config_2: "value 2"
}
// config2.json
{
"config_1": "value 1",
"config_2": "value 2"
}
Is there any advantages of using module.exports in config file? What are the differences?
javascript CommonJS Module
comments
conditionals
loops and such to populate defaults
code to change config based on NODE_ENV or similar
code to look for external files for SSL keys, API credentials, etc
easier to have fallbacks and defaults
JSON file
easy to parse and update with external tools
compatible with pretty much every programming language out there
pure data that can be loaded without being executed
easy to pretty print
JSON could start as the basis and all the code items described above about CommonJS module could live in a config.js module that reads config.json as it's starting point
So I always start with a commonjs module for the convenience, but keep any logic in there simple. If your config.js has bugs and needs tests, it's probably too complicated. KISS. If I know for a fact other things are going to want poke around in my config, I'll use a JSON file.
Thanks #jonathan-ong, looks like config.js (NOT JSON file) works as expected and I could put some comments.
module.exports = {
// Development Environment
development: {
database: {
host: '127.0.0.1',
login: 'dev',
password: 'dev'
}
},
// Production Environment
production: {
database: {
host: '127.0.0.1',
login: 'prod',
password: 'prod'
}
}
};
js files have their own perks as #Peter Lyons mentioned. But if I don't have to access external resources for API keys and etc. I would prefer JSON for config files.
Simple reason being I would not have to touch my code for just for the sake of making changes to config files. I can simply make an API to edit these json files to add,update or remove any configuration key-value pair. Even add whole new config file for a separate environment using an API.
And use config module to consume these configurations