How do I disable babel minification when not in production? - babeljs

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'));
});

Related

CLI arguments of create-nx-workspace

Is there some documentation regarding the arguments that create-nx-workspace takes? I'd like to build a copy and paste-able oneliner to set up a new workspace without any interactive questions asked. So far I have
npx create-nx-workspace#latest myworkspace --name myworkspace --preset web-components --appName myapp --cli angular
Next it's asking me which default stylesheet format I want to use. And I can't figure out how to specify that as a command line parameter.
Currently there is not option to define style within create-nx-workspace command. As you can see there is only prompt to inquire style after determination of appName promise:
determineWorkspaceName(parsedArgs).then(name => {
determinePreset(parsedArgs).then(preset => {
return determineAppName(preset, parsedArgs).then(appName => {
return determineStyle(preset).then(style => {
return determineCli(preset, parsedArgs).then(cli => {
const tmpDir = createSandbox(packageManager, cli);
createApp(tmpDir, cli, parsedArgs, name, preset, appName, style);
showCliWarning(preset, parsedArgs);
showNxWarning(name);
pointToTutorial(preset);
});
});
});
});
});
Code of the determineStyle is here.
I have already prepared PR to add this feature into create-nx-workspace command here.
You may select the tools used for styling the application
npx create-nx-workspace#latest myworkspace ... --style=css
You may use on of the following options
css, scss, less for Angular projects
styl for all non-Angular, and
styled-components, #emotion/styled, styled-jsx for React, Next.js and Gatsby.
Command line options for NX
You can check the command line options that you can use to create the NX workspace by running
npx create-nx-workspace#latest --help
The following are the command line options for the v13.4.5 version:
Option
Description
preset
Tools to be used in the workspace (options: "apps", "empty", "core", "npm", "ts", "web-components", "angular", "angular-nest", "react", "react-express", "react-native", "next", "gatsby", "nest", "express")
appName
Name of the application
cli
CLI to be used (options: "nx", "angular")
style
style option (options: "css", "scss", "less" for Angular, "styl" for all non-Angular and "styled-components", "#emotion/styled", "styled-jsx" for React, Next.js and Gatsby)
interactive
enable interactive mode when using presets (boolean)
packageManager
package manager to use (npm, yarn, pnpm)
nx-cloud
yse Nx Cloud (boolean)

How do I exclude babel plugins from certain environments?

I have .babelrc configured as something like this
{
"env" : {
"test": {
"plugins": [some other plugins...] //but not lodash
}
"plugins": ["lodash", some other plugins ...]
}
but this configuration isn't working. If i gave at cli BABEL_ENV=test <command> still lodash comes with it.
I even tried "exclude": ["babel-plugin-lodash"] in test. what is the correct way to exclude lodash from test enviroment but not in default run ?
I am trying to workaround this issue.
I tried work around suggested there but I want lodash in the default run too.Here default mean without BABEL_ENV=<env> in command line.
You need to ommit "babel-plugin-" when excluding iodash.
exclude": ["Iodash"]
More here: https://github.com/babel/babel/issues/9182

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"
},

Override JSHint Options by using the Grunt Command-Line

By calling
grunt jshint:path_to_file
I want to override the default JSHint configuration
grunt.initConfig({
jshint: {
options: {
curly: true,
eqeqeq: true,
eqnull: true,
browser: true,
globals: {
jQuery: true
}
},
all: ['Gruntfile.js', 'Scripts/src/**/*.js']
}
});
and only include that specific file.
"grunt jshint path_to_file" would also be okay yet I do not want to use the
grunt jshint --file=filePath
grunt.option function unless it can do what I need.
Is this achievable somehow?
The spirit of grunt is more to code which files to use in the gruntfile itself than specifying it on the command line.
So we would need more details on why you want to do that. I imagined 2 possibilities:
you only want to work on a subcomponent: in that case, you would declare different targets for each and call the targets from the command line: grunt jshint component1 with in your Gruntfile:
jshint: {
component1: [filePath1],
component2: [filePath2]
}
it's a performance issue: you only want to jshint some files because only them changed. In that case, combine grunt-contrib-watch (to run jshint on file change) and grunt-newer (to only run on the modified files)

Gulp + Browserify: CoffeeScript not loading when loading files from node_modules

After setting up the folder structure for my Gulp project, I was wondering how to do paths in browserify, and found this page: https://github.com/substack/browserify-handbook#organizing-modules. It recommends putting common application parts in a subfolder of node_modules. This appears to be working, it's getting the files, but it's not applying my coffeeify transform, so it's throwing errors because it's trying to interpret them as JS. Any ideas how to fix this? This is my browserify config:
browserify: {
// Enable source maps
debug: true,
// Additional file extentions to make optional
extensions: ['.coffee', '.hbs'],
// A separate bundle will be generated for each
// bundle config in the list below
bundleConfigs: [{
entries: src + '/javascript/app.coffee',
dest: dest,
outputName: 'app.js'
}, {
entries: src + '/javascript/head.coffee',
dest: dest,
outputName: 'head.js'
}]
}
and these are the relevant bits form my package.json.
"browserify": {
"transform": [
"coffeeify",
"hbsfy"
]
}
Transfroms aren't applied to files in node_modules unless they are marked as being global: https://github.com/substack/node-browserify#btransformtr-opts. If you choose to make it global, be warned, the documentation suggests against it:
Use global transforms cautiously and sparingly, since most of the time
an ordinary transform will suffice.
You won't be able to specify the tranform in package.json:
You can also not configure global transforms in a package.json like
you can with ordinary transforms.
The two options are programmatically, by passing {global: true} as options or at the command line with the -g option:
browserify -g coffeeify main.coffee > bundle.js