Publish a node module written in ES6 without providing the transpiled ES5 version b/c it is targeted for the latest browser - npm

My team will publish a node module written in ES6, targeted for the latest browsers. All the ES6 features we use, like async/await, import/export are supported by our target browsers. So I believe providing the transpiled ES5 version does not make sense (Our targeted audiences assure us they will only use the latest Chrome).
But I found without the transpiled ES5 version when they use our module, they got SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' even though their gulpfile already set
return browserify({ ... })
.transform(babelify.configure({
presets: ["es2015"]
}))
...
If they just include our module source codes in their own codes they can import my module without any error. That makes me believe there should be some setting in my module so I can just provide ES6 version only.
BTW, I have read How to publish a module written in ES6 to NPM?
and SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' - Wait what?
They were not my question and the answers there didn't fix the SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' my clients got.

I spent a whole day solving it so I would like to share my experience.
First of all, it is browserify's parser that complained SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' so what I need to do is to let the client's browserify transform my module and the solution turned to be quite simple!
Why aren't files in node_modules being transformed?
A possible solution is to add:
{ "browserify": {
"transform": ["babelify"] } } to the root of all your modules package.json that you want to be transformed.
So adding "browserify": { "transform": [ "babelify" ] } to my module's package.json and the the problem is solved!
It is easy to verify that, e.g. in my module's .babelrc I particularly set "modules":false (b/c defaults to "commonjs")
{ "presets": [[
"env",
{
"modules":false,
"debug": true
}
]]}
Then I got SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' again!
PS,
I got more than one comments/answers said <script type="module". Of course I knew script has type="module" but that is the wrong answer!
Because we are talking using node module in browser environment, type="module" can't solve the problem of import module from node_modules

Related

React Native test with Jest and react-native-ble-plx library fails because "Jest encountered an unexpected token"

Trying to execute that must be a simple screen test, I found this error. I saw some related issues and solutions touching babel and jest config but I did not found the proper way to solve it.
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/.../node_modules/react-native-ble-plx/index.js:3
export { BleError, BleErrorCode, BleAndroidErrorCode, BleIOSErrorCode, BleATTErrorCode } from './src/BleError'
^^^^^^
SyntaxError: Unexpected token 'export'
Any suggestion? Thanks!
Finally was solved adding it to jest.config.js:
transformIgnorePatterns: [
'<rootDir>/node_modules/(?!(jest-)?#?react-native|#react-native-community|#react-navigation)',
],
Source: related issue on github
https://github.com/callstack/react-native-testing-library/issues/703

Vue not working in IE11 despite Babel Polyfill

unfortunately, my most recent application is required to support Internet Explorer 11. This requirement came somewhat suprising to me, so I already built the applications frontend with Vue.js. The backend is written in Laravel, therefore I use laravel-mix/webpack.
This is my app.js:
require('./bootstrap');
window.Vue = require('vue');
Obviously, IE11 doesn't support Vue.js so I tried the following ways of transpiling/polyfilling the code.
1. requiring polyfill
Approach: Adding require("#babel/polyfill"); to the top of my app.js as described in https://babeljs.io/docs/en/babel-polyfill
Result: Following Error Message shown in IE console:
SCRIPT1003: ':' expected
Clearly a compatibility issue, since pre data(){} is invalid in ES < 5
2. using mix.babel
Approach: Adding mix.babel(['resources/js/app.js'], 'resources/js/app.js') to my webpack.mix.js as described in https://laravel.com/docs/5.8/mix (I am using laravel 5.8.36). My webpack.mix.js now looks like this:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js/app.js')
mix.babel(['resources/js/app.js'], 'resources/js/app.js')
mix.sass('resources/sass/app.scss', 'public/css');
Result: Same Error Message as in 1
3. using an mix extension
Approach: Installing this extension: https://laravel-mix.com/extensions/polyfill and configure my webpack.mix.js as described. My webpack.mix.js now looks like this:
const mix = require('laravel-mix');
require('laravel-mix-polyfill');
mix.js('resources/js/app.js', 'public/js/app.js')
mix.sass('resources/sass/app.scss', 'public/css');
mix.polyfill({
enabled: true,
useBuiltIns: "usage",
targets: {"firefox": "50", "ie": "11"}
})
Result: Again, the same Error Message as in 1
4. manually transpiling with babel-cli
Approach: Merely out of desperation I tried to manually transpile my app.js with the following command ./node_modules/.bin/babel ./public/js/app.js --out-dir ./public/js/
Result: Stil no luck, same error as in 1
I am really starting to get frustrated, so any help is much appreciated.
If you can't get Babel-Polyfill to work, you could try using Polyfill.io, which automatically polyfills the selected Polyfills if the browser requires them.
All you need to do is go the Create a polyfill bundle page, and select the polyfills you need. Then once you've made your bundle, copy the URL at the top and add a <script> tag with said URL to your head.
I personally haven't used it with Laravel, but I've previously fought with babel-polyfill myself, and ended up using Polyfill.io since i couldn't get babel-polyfill to work.

ES6 import and npm packages

Anyone got a link to documentation explaining exactly how ES6 import is supposed to work with npm packages (as opposed to javascript module files) ?
Also (and possibly related) a link to documentation on the use/significance of "module" as a top-level key in an npm package.json file ?
Eg. consider the following from juggle/resize-observer ;
package.json
{
...
"module": "lib/exports/resize-observer.js",
...
}
consumer javascript file
import { ResizeObserver } from '#juggle/resize-observer';
On the above import Chrome sends a request to the server for '#juggle/resize-observer' which is a directory..... so what happens next ? (I don't have a working instance of this and my server doesn't return anything yet as I don't know what it's supposed to / in what format ). Is this syntax only for use with some sort of build tool where it ultimately gets replaced with the actual file ?
I have looked at the npm site/googled and cannot find any relevant documentation.
UPDATE Still waiting for a link to relevant documentation (no relevant Google results at this time) but for anyone asking the same question: apparently you need your server to do "module resolution" . Alternatively you can use Snowpack or a bundler eg. Webpack.
Apparently npm/node packages are not packaged with browsers in mind or based on any W3C/Web Modules standard specification.
See here for module resolution info.
So at present to use an npm package in a browser you must do one of the following
use a bundler like webpack
use snowpack
use a CDN which resolves the module request
implement npm module resolution in your own server
Find the package entry point and use that in your ES6 import statement.
However, if the package's json "main" property changes in a subsequent update you
will need to update your code to reflect this.

async-storage SyntaxError Unexpected identifier while transpiling with Babel7

After using #react-native-community/async-storage and transpile it with the following npm command in my react-native environment.
"test": "NODE_ENV=test ./node_modules/.bin/mocha --timeout 5000 --require #babel/register \"./src/shared/__tests__/**/*.spec.js\""
I did some research and in no vain. But I found it happens to Jest too.
jest test fails after installing react-native-async-storage
this is my babel.config.js
module.exports = {
env: {
production: {
},
test: {
presets: [
'#babel/preset-env'
],
},
},
};
I'm only testing non-jsx code only so #babel/preset-env seems to be working alright.
node_modules/#react-native-community/async-storage/lib/index.js:5
import AsyncStorage from './AsyncStorage';
^^^^^^^^^^^^
SyntaxError: Unexpected identifier
It seems like no one likes to answer jest newbie questions....
anyway, when starting to learn jest, I encountered some funny error messages that doesn't reflect the actual error. There are some possible situations a developer can consider.
You didn't to mock your module say A_module that is inside node_modules so one of the modules say B_modules inside A_modules uses a NativeModules from react so Jest cannot performa a test. Please look at stack trace or use a debugger to find out which one you prefer to mock.
Mock a module that uses NativeModules (similar to point 1, but more direct and concise )
You need to understand jest more thoroughly before you proceed. Reading documentation is good but jump to example when you think fit. especially check out the examples that you really need and read related ones. Many of the time, either your Babel setting or mocking methods is incorrect.
use jest.mock instead of jest.genMockFromModule. Why? there are some functions or init function that causes your test to crash at this statement. Because it calls NativeModules or something jest doesn't allow. use mock instead.
Solutions to this question: please refer to this most updated solution.
thanks

Can't get es6 to work with Gulp

This is driving me insane, so I'm hoping someone might see something that I'm missing. Thank you for your help in advance.
I have a gulp file and I have installed via npm, babel-core, babel-preset-es2015, babel-preset-react. From researching online and in high hopes even though this might not be right, I have renamed the gulp file to be gulpfile.babel.js and I have created a .babelrc file with
{
"presets": ["es2015"]
}
I am using browsersync and when I launch the gulp task the html file loads, but the index.js I have includes 'import React....'. This files causing the error in the JS console that says 'Uncaught SyntaxError: Unexpected token import'.
I thought the es2015 npm packages I have should be taking care of that ES6 syntax?
In the gulp file the task that I thought was suppose to take care of that is;
// convert jsx to JS
gulp.task('babelFiles', function() {
return gulp.src('js/*.(jsx|js)')
.pipe(babel({
compact: false
}))
.pipe(gulp.dest('js'))
.pipe(browserSync.reload({
stream: true
}))
});
The gulp task that is responsible for launching this is:
// Default task
gulp.task('default', ['babelFiles', 'browserSync']);
I am puzzled as to what could be wrong here?
Any ideas would be much much appreciated!
There are two problems:
Gulp seems like doesn't support you syntax for file extension mask:
gulp.src('js/*.(jsx|js)') // not working
gulp.src('js/*.{js,jsx}') // working
You piping from js directory to js directory but since there are no matches because of the problem (1) it makes you believe the babel is not working
Update
Gulp uses glob syntaxt to match files - according to glob syntax the qualifier for amount of items should be included before ( | ) - in our case following syntax would be valid
gulp.src('js/*.#(js|jsx)')
where # means match exactly one occurrence of pattern after #.
In your case there was no qualifier presented