vuejs use babel plugin-proposal-class-properties - vue.js

I have a class where I use some static properties like this:
class Entity {
static LIMIT = 10;
}
So, i can do:
Entity.LIMIT
In order to do that I'm using babel plugin-proposal-class-properties and in my .babelrc I have:
{
"presets": ["#babel/preset-env"],
"plugins": [
["#babel/plugin-proposal-class-properties", { "loose": true }]
]
}
I'm using jest and my test passes using that config. Now I need to use funcionality of Entity class inside a vuejs component. But I got the error:
Module parse failed: Unexpected token. You may need an appropriate loader to handle this file type
I also tried a babel config file in my project root: babel.config.js
module.exports = {
presets: ["#babel/preset-env"],
plugins: [
["#babel/plugin-proposal-class-properties", { "loose": true }]
]
};
But didn't work.
How can i configure vuejs, to make work this babel plugin?
I'm using vue2.6.11 and vue-cli 3

I got this exact same issue when trying to use "importabular" with vuejs (vuejs 2, vue-cli-3). Importabular uses class properties, after some research I found this babel plugins (plugin-proposal-class-properties), I installed it and added it in vue.config.js.
To finally make it work, I had to add "importabular" (or the nested path) in the transpileDependencies: option. Why that? Because, by default, Babel ignores whatever is in node_module, so you have to tell Babel to not ignore this specific folder.
So, if you want to use babel or some babel plugins with some node_module with vue you should modify the vue.config.js as follow :
module.exports = {
transpileDependencies: [
'path/in/node_module',
],
}
and change the babel.config.js as follow:
module.exports = {
"presets": [
"#vue/cli-plugin-babel/preset"
],
"plugins": [
["#babel/plugin-proposal-class-properties"],
]
}

Related

Next.js: Jest encountered an unexpected token. Jest failed to parse a file. Crashing due to dot ( .{color: red} ) before a className in CSS files [duplicate]

I am trying to get my first Jest Test to pass with React and Babel.
I am getting the following error:
SyntaxError: /Users/manueldupont/test/avid-sibelius-publishing-viewer/src/components/TransportButton/TransportButton.less: Unexpected token
> 7 | #import '../variables.css';
| ^
My package.json config for jest look like this:
"babel": {
"presets": [
"es2015",
"react"
],
"plugins": [
"syntax-class-properties",
"transform-class-properties"
]
},
"jest": {
"moduleNameMapper": {
"^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
"^[./a-zA-Z0-9$_-]+\\.png$": "RelativeImageStub"
},
"testPathIgnorePatterns": [
"/node_modules/"
],
"collectCoverage": true,
"verbose": true,
"modulePathIgnorePatterns": [
"rpmbuild"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react/",
"<rootDir>/node_modules/react-dom/",
"<rootDir>/node_modules/react-addons-test-utils/",
"<rootDir>/node_modules/fbjs",
"<rootDir>/node_modules/core-js"
]
},
So what am I missing?
moduleNameMapper is the setting that tells Jest how to interpret files with different extension. You need to tell it how to handle Less files.
Create a file like this in your project (you can use a different name or path if you’d like):
config/CSSStub.js
module.exports = {};
This stub is the module we will tell Jest to use instead of CSS or Less files. Then change moduleNameMapper setting and add this line to its object to use it:
'^.+\\.(css|less)$': '<rootDir>/config/CSSStub.js'
Now Jest will treat any CSS or Less file as a module exporting an empty object. You can do something else too—for example, if you use CSS Modules, you can use a Proxy so every import returns the imported property name.
Read more in this guide.
I solved this by using the moduleNameMapper key in the jest configurations in the package.json file
{
"jest":{
"moduleNameMapper":{
"\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
"\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
}
}
}
After this you will need to create the two files as described below
__mocks__/styleMock.js
module.exports = {};
__mocks__/fileMock.js
module.exports = 'test-file-stub';
If you are using CSS Modules then it's better to mock a proxy to enable className lookups.
hence your configurations will change to:
{
"jest":{
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
},
}
}
But you will need to install identity-obj-proxy package as a dev dependancy i.e.
yarn add identity-obj-proxy -D
For more information. You can refer to the jest docs
UPDATE who use create-react-app from feb 2018.
You cannot override the moduleNameMapper in package.json but in jest.config.js it works, unfortunately i havent found any docs about this why it does.
So my jest.config.js look like this:
module.exports = {
...,
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(scss|sass|css)$": "identity-obj-proxy"
}
}
and it skips scss files and #import quite well.
Backing my answer i followed jest webpack
Similar situation, installing identity-object-proxy and adding it to my jest config for CSS is what worked for me.
//jest.config.js
module.exports = {
moduleNameMapper: {
"\\.(css|sass)$": "identity-obj-proxy",
},
};
The specific error I was seeing:
Jest encountered an unexpected token
/Users/foo/projects/crepl/components/atoms/button/styles.css:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.button { }
^
SyntaxError: Unexpected token .
1 | import React from 'react';
> 2 | import styles from './styles.css';
If you're using ts-jest, none of the solutions above will work! You'll need to mock transform.
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
roots: [
"<rootDir>/src"
],
transform: {
".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest-config/file-mock.js",
'.(css|less)$': '<rootDir>/jest-config/style-mock.js'
},
};
file-mock.js
module.exports = {
process() {
return `module.exports = 'test-file-stub'`;
},
};
style-mock.js
module.exports = {
process() {
return 'module.exports = {};';
}
};
I found this working example if you want more details.
Solution of #import Unexpected token=:)
Install package:
npm i --save-dev identity-obj-proxy
Add in jest.config.js
module.exports = {
"moduleNameMapper": {
"\\.(css|less|scss)$": "identity-obj-proxy"
}
}
Update: Aug 2021
If you are using Next JS with TypeScript. Simply follow the examples repo.
Else you will be wasting days configuring the environment.
https://github.com/vercel/next.js/tree/canary/examples/with-jest
I added moduleNameMapper at the bottom of my package.json where I configured my jest just like this:
"jest": {
"verbose": true,
"moduleNameMapper": {
"\\.(scss|less)$": "<rootDir>/config/CSSStub.js"
}
}

VueJs 3 + Vuetify: Not working in IE and Edge

I'm not sure what I'm doing wrong here. I have VueJs 3 with Vuetify. Works great with Chrome and Firefox, but it is not loading in IE and Edge. I am attempting to load polyfills with Babel and forcing Vue CLI to transpile dependencies for Vuetify.
package.json
"babel": {
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}
vue.config.js
module.exports: {
transpileDependencies: ['vuetify']
}
main.ts
import 'core-js/es6';
import 'regenerator-runtime/runtime';
The imports are included at the top of my main.ts file. I have been using the official documentation to set this up.
What am I missing here?
If you created the project using vue-cli and added vuetify using vue add vuetify, then the solution to make it work in Edge should be to add transpileDependencies: ['vuetify'] to the vue.config.js file.
But in my case I added vue/vuetify to an already existing project and did not use vue-cli. So to make it work I installed core-js npm install core-js#2 --save and added this to the rules in my webpack.config.js
{
test: /\.js$/,
exclude: /node_modules\\(?!(vuetify)).*/,
use: [
{
loader: 'babel-loader',
options: {
configFile: './babel.config.js',
}
}
]
}
Then I added the babel.config.js file to the root of the project.
module.exports = {
presets: [
['#babel/preset-env', {
debug: true,
useBuiltIns: 'usage',
corejs: { "version": 2, "proposals": true }
}],
],
plugins: [
'#babel/plugin-proposal-object-rest-spread',
'#babel/plugin-transform-spread',
]
}
A little late reply, but I couldn't find this solution anywhere else and this was one of the first posts showing up when I was searching for it myself. So I figured I'll post what worked for me here.
I ended up just removing Vuetify (I was only using one feature from it which was easily replaced) and using the babel polyfill cdn. Probably not the best solution but got it working for now.

Vue components does not appear on IE11 (Laravel)

All my vue components cannot be rendered in IE11. After searching, it looks like the reason is that IE does not support ES6 and above.
So my attempt at the moment is use babel:
My .babelrc:
{
"presets": [
[
"#babel/preset-env",
{
"debug": true,
"modules": false,
"forceAllTransforms": true,
"useBuiltIns": "usage",
"targets": "last 1 version, > 1%",
"corejs": 3
}
]
]
}
And I am using laravel-mix to compile the asset:
const mix = require("laravel-mix")
mix.js("resources/js/app.js", "public/js/app.js")
.sass("resources/sass/app.scss", "public/css/app.css")
.options({
processCssUrls: false
});
The compilation was running ok, but my vue components are still not rendered.
Any pointers to solve the problem?
Thanks.
// SOLUTION: Convert ES6 to ES2015 using babel and laravel-mix
Try this.
Install babel polyfill
npm install --save #babel/polyfill or yarn add #babel/polyfill
Add the code import #babel/polyfill to src/main.js.
import '#babel/polyfill'
import Vue from 'vue'
// ...
Change the babel.config.js as follows:
module.exports = {
presets: [
[
'#vue/app',
{
'useBuiltIns': 'entry'
}
]
]
}
Create the vue.config.js file and create:
(Add existing settings if they already exist.)
const ansiRegex = require('ansi-regex')
module.exports = {
......(기존 설정이 있다면 다음에 추가)
transpileDependencies: [ansiRegex]
}
Note. Use es6-promise when using a promise pattern.

Vue - Compile other folder outside of /src in Vue.js project

I have a regular Vue.js project (created using v3.0.3) that uses WebSockets. Also in the project root is the /server folder which has the Node.js code that houses the multi-player aspect and socket code.
However, since the folder /server is independent of the /src folder from the Vue.js project, how do I make use of the Vue CLI webpack config and add babel compiling (using Webpack) to appropriately compile both the /src
https://cli.vuejs.org/guide/webpack.html#simple-configuration
I was able to import babel-cli and just compile/run like so:
./node_modules/.bin/nodemon --exec babel-node --presets env,stage-2 server.js
and it worked.
Actually, you should add .babelrc file and declare presets, env options and etc into it.
I don't know why you don't eject, because of access to webpack configuration. In the webpack config, you can declare your src folder or exclude other folders like node_modlules or your custom server folder.
For example, see webpack config for your issue:
module.exports = {
~~~
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: ['node_modules', 'server'],
use: [
{
loader: 'babel-loader',
},
],
},
~~~
And see a sample .babelrc file:
{
"presets": [
"es2015",
"es2016",
"es2017",
"env",
"stage-0"
],
"plugins": [
"transform-class-properties",
"transform-object-rest-spread",
[
"transform-runtime",
{
"helpers": true,
"polyfill": true,
"regenerator": true
}
]
],
"env": {
"development": {
"compact": false
}
}
}
Then you should use your webpack commands to build:
webpack -p --config ./webpack.production.config.js

How do I resolve import with absolute path?

What do I need to setup in brunch-config.js to be able to resolve absolute path from project's root folder? i.e
import { helper } from '/imports/utilities/helper'
The reason being is I have a legacy React app and it imports local files by using relative path. While I'm trying to use brunch, I need to figure out a way to setup brunch so that it understands the path without having to change the code.
I tried to use npm alias but not sure how it works
npm: {
aliases: {
'/imports': 'imports/**'
}
}
Found the solution with babel-plugin-module-resolver package.
Since all my codes are under /imports dir, in brunch-config.js I setup an alias based on their documentation:
plugins: {
babel: {
plugins: [
...,
["module-resolver", {
"root": ["./imports"],
"alias": {
"/imports": ([, path]) => `./imports${path}`,
}
}]
],
presets: [
...
],
}
},
That way, if I do import Screen from '/imports/components/screens' it will resolve the file under ./imports/components/screens
You can set the alias in .babelrc too but you might want to use regex instead.