How to disable strictMode in Babel.confict.js for Rails? [duplicate] - ruby-on-rails

I'm using function form of "use strict" and don't want global form which Babel adds after transpilation. The problem is I'm using some libraries that aren't using "use strict" mode and it might throw error after scripts are concatenated

As it has already been mentioned for Babel 6, it's the transform-es2015-modules-commonjs preset which adds strict mode.
In case you want to use the whole es2015 preset without module transformations, put this in your .babelrc file:
{
"presets": [
["es2015", { "modules": false }]
]
}
This will disable modules and strict mode, while keeping all other es2015 transformations enabled.

Babel 5
You'd blacklist "useStrict". For instance here's an example in a Gruntfile:
babel: {
options: {
blacklist: ["useStrict"],
// ...
},
// ...
}
Babel 6
Since Babel 6 is fully opt-in for plugins now, instead of blacklisting useStrict, you just don't include the strict-mode plugin. If you're using a preset that includes it, I think you'll have to create your own that includes all the others, but not that one.

There's now a babel plugin that you can add to your config that will remove strict mode: babel-plugin-transform-remove-strict-mode. It's a little ugly in that the "use strict" gets added and then removed, but it makes the config much nicer.
Docs are in the GitHub repo:
https://github.com/genify/babel-plugin-transform-remove-strict-mode
Your .babelrc ends up looking like this:
{
"presets": ["env"],
"plugins": ["transform-remove-strict-mode"]
}

I also came accross this rather ridiculous limitation that you cannot disable or overwrite settings from an existing preset, and have resorted to using this preset instead: https://www.npmjs.com/package/babel-preset-es2015-without-strict

plugins: [
[
require("#babel/plugin-transform-modules-commonjs"),
{
strictMode: false
}
],
]

You can tell babel that your code is a script with:
sourceType: "script"
in your babel config file. This will not add use strict. See sourceType option docs
Source: https://github.com/babel/babel/issues/7910#issuecomment-388517631

Babel 6 + es2015
We can disabled babel-plugin-transform-es2015-modules-commonjs to require babel-plugin-transform-strict-mode.
So comment the following code in node_modules/babel-plugin-transform-es2015-modules-commonjs/lib/index.js at 151 line
//inherits: require("babel-plugin-transform-strict-mode"),

just change .babelrc solution
if you don't want to change any npm modules, you can use .babelrc ignore like this
{
"presets": ["es2015"],
"ignore": [
"./src/js/directive/datePicker.js"
]
}
ignore that file, it works for me!
the ignored file that can't use 'use strict' is old code, and do not need to use babel to transform it!

Personally, I use the gulp-iife plugin and I wrap IIFEs around all my files. I noticed that the babel plugin (using preset es2015) adds a global "use strict" as well. I run my post babel code through the iife stream plugin again so it nullifies what babel did.
gulp.task("build-js-source-dev", function () {
return gulp.src(jsSourceGlob)
.pipe(iife())
.pipe(plumber())
.pipe(babel({ presets: ["es2015"] }))// compile ES6 to ES5
.pipe(plumber.stop())
.pipe(iife()) // because babel preset "es2015" adds a global "use strict"; which we dont want
.pipe(concat(jsDistFile)) // concat to single file
.pipe(gulp.dest("public_dist"))
});

This is not grammatically correct, but will basically work for both Babel 5 and 6 without having to install a module that removes another module.
code.replace(/^"use strict";$/, '')

Since babel 6 you can install firstly babel-cli (if you want to use Babel from the CLI ) or babel-core (to use the Node API). This package does not include modules.
npm install --global babel-cli
# or
npm install --save-dev babel-core
Then install modules that you need. So do not install module for 'strict mode' in your case.
npm install --save-dev babel-plugin-transform-es2015-arrow-functions
And add installed modules in .babelrc file like this:
{
"plugins": ["transform-es2015-arrow-functions"]
}
See details here: https://babeljs.io/blog/2015/10/31/setting-up-babel-6

For babel 6 instead of monkey patching the preset and/or forking it and publishing it, you can also just wrap the original plugin and set the strict option to false.
Something along those lines should do the trick:
const es2015preset = require('babel-preset-es2015');
const commonjsPlugin = require('babel-plugin-transform-es2015-modules-commonjs');
es2015preset.plugins.forEach(function(plugin) {
if (plugin.length && plugin[0] === commonjsPlugin) {
plugin[1].strict = false;
}
});
module.exports = es2015preset;

Please use "es2015-without-strict" instead of "es2015". Don't forget you need to have package "babel-preset-es2015-without-strict" installed. I know it's not expected default behavior of Babel, please take into account the project is not mature yet.

I just made a script that runs in the Node and removes "use strict"; in the selected file.
file: script.js:
let fs = require('fs');
let file = 'custom/path/index.js';
let data = fs.readFileSync(file, 'utf8');
let regex = new RegExp('"use\\s+strict";');
if (data.match(regex)){
let data2 = data.replace(regex, '');
fs.writeFileSync(file, data2);
console.log('use strict mode removed ...');
}
else {
console.log('use strict mode is missing .');
}
node ./script.js

if you are using https://babeljs.io/repl (v7.8.6 as of this writing), you can remove "use strict"; by selecting Source Type -> Module.

Using plugins or disabling modules and strict mode as suggested in the #rcode's answer didn't work for me.
But, changing the target from es2015|es6 to es5 in tsconfig.json file as suggested by #andrefarzart in this GitHub answer fixed the issue.
// tsconfig.json file
{
// ...
"compilerOptions": {
// ...
"target": "es5", // instead of "es2015"
}

Related

Plugin strip ~ How to exclude a specific file whose extension was included generally?

I'm using the rollup plugin strip to exclude the console.logs in the production built with following settings
plugins: [
strip({
include: ['**/*.(js|svelte)'],
labels: ['dev'],
functions: ['console.log'],
})
]
I now have the situation that I would like to keep one special log in production. So I created a function in a new file logInProduction.js
export function logInProduction(msg) {
console.log(msg)
throw new Error('PRODUCTION')
}
and added the file to the plugin options by adding this line
exclude: ['logInProduction.js'],
But when calling the function, the error is thrown, so the function was called, but the log before doesn't appear.
Is this because the .js ending is generally included before so the specific exclusion doen't have any effect? Is it possible to do this?
Or is there another maybe better way to keep one specific console.log?
Problem was, that the filename was missing the directory, so
exclude: ['src/utils/logInProduction.js'],
or
exclude: ['**/logInProduction.js'],
does work

How to make ionide-fsharp formater work in VSCode

I have a problem with ionide-fsharp formatter. When I install the extension in VSCode I am not able to automaticaly format a file on save. I have fantomas installed globaly and I tried to go through FSAC, but nothing has helped. I think that I need to put something in VSCode's settings.json like I have a prettier config for typescript.
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
So this is how my own config looks like
"[fsharp]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "Ionide.Ionide-fsharp"
},
You should ensure that editor.formatOnSave is set to true (either for just the fsharp language or globally) and then FSAC should pick up your globally-installed Fantomas.

How do I add an additional postcss plugin via the new #angular/cli v7 angular.json or custom-webpack.config.js?

#angular/cli#7+ allows a customWebpackConfig to be specified to provide custom webpack configuration, such as:
"architect": {
"build": {
"builder": "#angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./build/custom-webpack.config.js",
"mergeStrategies": {
"externals": "prepend"
}
},
...
This file then technically allows you to prepend, append or replace any portion of the webpack configuration. Prior to upgrading to #angular#7.1.3 and #angular/cli#7.1.3 we had ejected the webpack configuration to make some additions. One such addition was the postcss-momentum-scrolling postcss-loader plugin that automatically enabled iOS momentum scrolling on all scrollable containers.
I am seeking support on figuring out how to generate the necessary custom webpack code to load this plugin via the supported customizations allowed by #angular/cli#7+.
Here is a sample of what I have tried in my custom-webpack.config.js file:
const postcssMomentumScrolling = require('postcss-momentum-scrolling');
module.exports = {
module: {
rules: [
{
test: /\.scss$|\.sass$/,
use: [
{
"loader": "postcss-loader",
"options": {
"plugins": [
postcssMomentumScrolling(),
]
}
}
]
},
],
},
};
As soon as I touch the scss chunk of the webpack config, it seems to do a replace instead of a merge or prepend, breaking the build.
I am wondering if anyone has a guide or suggestions on how to see what the initial webpack configuration that #angular/cli generates that is the starting point for modifications and a way to preview/peek at the code to be executed as debugging.
Also, an example of a similar customization would be great.
Thanks!
I think you need to tell to "customWebpackConfig" which portion to merge. Like this:
"mergeStrategies": {
"module.rules": "prepend"
}
In this way you're going to tell to merge with prepend strategy.
According to "custom-webpack" documentation it should default to "append" which doesn't seem the case in your example.
It's been a while since you've put the question but I wanted to actually ask if you have been able to fix it since I'm running in some issues getting my "module.rules" merged...it seems to work only if I set "replace" strategy.

Rails 5.1 Angular templateUrl

Question
What do I need to do to get my Angular application to allow me to use the templateUrl property of the Component decorator? When you create a new Rails 5.1 application and use the flag --webpack=angular, it gives you a proof of concept Angular application, but as soon as I started creating more components, I began to recognize that I don't know how to refer to the correct path that the templates are being served. I'm not even sure if they are being served, to be honest.
What I've tried
Tried many different variations of the path, from just the file name all the way to the root of the application, one folder at a time.
Googling for someone else running into the same problem.
include the CommonModule in my imports in app.module.ts.
Background
I'm really used to using the Angular CLI and I don't remember ever having an issue using the templateUrl property. What is different about an Angular CLI project to what's given to you in a Rails 5.1 app in terms of configuration affecting templates? Would I be able to use Angular CLI in a Rails 5.1 app without having to change much of the Rails app itself?
Can be done. But this needs a different webpack loader setup and several minor tweaks.
But first: shopping!
$ yarn add \
html-loader \
awesome-typescript-loader \
angular2-template-loader \
#types/node \
--dev
With all required packages installed replace config/webpack/loaders/angular.js with this:
const {env} = require('../configuration.js');
isProd = env.NODE_ENV === 'production';
module.exports = {
test: /\.ts$/,
use: [
{
loader: 'awesome-typescript-loader',
options: { useCache: !isProd }
},
'angular2-template-loader'
]
};
angular2-template-loader scans your Component decorators for the templateUrl argument and replaces it with something like template: require('...')'. The require() call is the reason for installing #types/node by the way.
awesome-typescript-loader is a bit more optimized than the default ts-loader (which will probably work here as well, but I didn't test it).
So far so good. Next we need to tell webpack how to actually load HTML files. Add config/webpack/loaders/html.js with the following content:
module.exports = {
test: /\.html$/,
loader: 'html-loader',
};
Nothing obscure here. Moving on.
In your Javascript app add type informations for *.html files to app/javascript/hello_angular/html.d.ts:
declare module "*.html" {
const content: string
export default content
}
This tells the TypeScript compiler that require('template.html') returns a string.
Last but not least you have add .html to the recognized extensions in config/webpacker.yml:
default: &default
# ...
extensions:
# ...
- .html
# ...
Now you should be good to go:
import { Component } from '#angular/core';
#Component({
selector: 'hello-angular',
templateUrl: './template.html'
})
export class AppComponent {
name = 'Angular!';
}
Don't forget to restart bin/webpack-dev-server.
Theoretically you could do the same for styleUrls. But this is more tangled with rails/webpacker and you would loose some of it's features.

Gulp task to bundle bower_components?

I'd appreciate it so much if someone could please tell me a good way to handle bundling bower components. I feel like I've tried everything... Although, I can't seem to find any gulp tasks that handle this already. Could it really not exist?
Let's say it doesn't exist. Worst case scenario is I have to specify the paths of each "dist" file from bower_components folder. (It is annoying that each component seems to have its own "dist" folder... nothing is standardized.)
So even if I do that, I've noticed some components like 'active-support' seem to have require('lodash') and such in them. I think that if I just simply copy that file, it will break because the requires won't resolve.
What am I missing? How do I simply take all bower_components and bundle into a "common.js"... is there a way or is it a clusterfluck?
Update
As pointed out by Alerty, the new Gulp policy seems to be: use bower directly and glob patterns (and hope that the packages maintainers have a proper "ignore" properties).
Previously
You can use main-bower-files or gulp-bower-src to get files from your bower components. They can also use "ignore" or "main" overrides in your own bower file.
This is how I managed it (but see gulpfile.js for project structure, it's not a single gigantic gulpfile) :
https://github.com/notbrain/viceroy/blob/master/gulp/tasks/bower.js
Would be a bit more modular to simply concat all bower deps and then do the uglify() and minifyCSS() tasks separately on dist/ source locations, based on dev/prod env targets, but will have to wait for future updates.
Use main-bower-files:
var gulp = require('gulp');
var mainBowerFiles = require('main-bower-files');
gulp.task('TASKNAME', function() {
return gulp.src(mainBowerFiles())
.pipe(/* what you want to do with the files */)
});
if you have folders like:
-app
-bower
-node_modules
Gulpfile.js
package.json
the solution are:
gulp.task("connect", function () {
connect.server({
root: ["app"],
livereload: true,
port: 8034,
middleware: function (connect) {
return [connect().use("/bower", connect.static("bower"))];
}
});
});
If your project use AMD specification.
You can use gulp-edp bundle the modules.
set module info at module.conf
{
"baseUrl": "src",
"paths": {},
"packages": [
{
"name": "etpl",
"location": "../bower_components/etpl/3.0.1/src",
"main": "main"
},
{
"name": "jquery",
"location": "../bower_components/jquery/1.9.1/src",
"main": "jquery.min"
}
],
"combine": {
"app": true
}
}
gulpfile.js
var gulp = require('gulp');
var edp = require('gulp-edp');
gulp.src(
[
'src/**/*.js'
'bower_components/**/*.js',
'!bower_components/**/{demo,demo/**}',
'!bower_components/**/{test,test/**}'
]
)
.pipe(edp({
getProcessors: function () {
var moduleProcessor = new this.ModuleCompiler();
return [moduleProcessor];
}
}))
.pipe(gulp.dest('dist'));
See EDP wiki for more features.

Resources