I am using craco and trying to figure out how to configure jsx. I keep getting the following error
Support for the experimental syntax 'jsx' isn't currently enabled (4:17):
They suggest that I add `babel/preset-react or use #babel/plugin-syntax-jsx to the plugin section to enable parsing but I'm unsure how to do that.
To clarify, I am trying to use a src folder outside the root of my react-app
craco.config.js
module.exports = {
webpack: {
alias: {},
plugins: {
add: [] /* An array of plugins */,
remove:
[] /* An array of plugin constructor's names (i.e. "StyleLintPlugin", "ESLintWebpackPlugin" ) */,
},
configure: {
/* Any webpack configuration options: https://webpack.js.org/configuration */
},
configure: (webpackConfig, { env, paths }) => {
console.log("WEBPACK");
console.log(webpackConfig);
webpackConfig.entry =
"C:\\Users\\danie\\Desktop\\Code\\JS\\npm_packages\\source\\src\\index.js";
return webpackConfig;
},
},
babel: {
presets: [],
plugins: [],
loaderOptions: (babelLoaderOptions, { env, paths }) => {
console.log("BABEL");
console.log(babelLoaderOptions);
return babelLoaderOptions;
},
},
};
Figured out my issue by adding the preset to my config file
craco.config.js
babel: {
presets: ['#babel/preset-react'],
// plugins: [],
loaderOptions: (babelLoaderOptions, { env, paths }) => {
console.log("BABEL");
console.log(babelLoaderOptions);
return babelLoaderOptions;
},
},
Related
Maybe I'm misinterpreting what source maps should do in a Vue app, but shouldn't I get the *.vue file line number where the error is occurring? I always get a refernce to a line number in a vue.runtime.esm.js file. It references the component, but the line number in the component file would be more helpful. Do I need to install additional source map modules?
My vue.config is below:
module.exports = {
assetsDir: "",
publicPath: "/",
css: {
sourceMap: true,
loaderOptions: {
sass: {
sassOptions: {},
},
},
},
configureWebpack: (config) => {
if (process.env.NODE_ENV === "development") {
config.devtool = "eval-source-map";
config.output.devtoolModuleFilenameTemplate = (info) =>
info.resourcePath.match(/^\.\/\S*?\.vue$/)
? `webpack-generated:///${info.resourcePath}?${info.hash}`
: `webpack-yourCode:///${info.resourcePath}`;
config.output.devtoolFallbackModuleFilenameTemplate =
"webpack:///[resource-path]?[hash]";
}
},
};
This also doesn't work:
configureWebpack: (config) => {
config.devtool = "source-map";
},
I had to use 'cheap-module-source-map' instead of 'eval-source-map'. In the end it would look like this:
configureWebpack: (config) => {
if (process.env.NODE_ENV === "development") {
config.devtool = "cheap-module-source-map";
[...]
}
},
I am not really strong with setting up my custom npm packages, therefore I am asking for help. I am trying to test my custom ESLint plugin rules on another project. For this, I have set up two projects in one root directory and linked them, using the file linking option (find the image of the file structure attached):
"eslint-plugin-winniepukki-guidelines": "file:../guide"
.eslintrc configuration file on the project, where I want to use my custom ESLint plugin:
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
'airbnb-base',
],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
},
plugins: [
'winniepukki-guidelines',
],
rules: {
'winniepukki-guidelines/use-license': 'error',
'winniepukki-guidelines/avoid-names': 'error',
},
};
Unfortunately, the rules do not apply properly with the following error:
Definition for rule 'winniepukki-guidelines/avoid-names' was not found.eslint(winniepukki-guidelines/avoid-names). This is how the avoid-names.js file looks like:
module.exports = {
meta: {
messages: {
avoidName: "Avoid using variables named '{{ name }}'"
}
},
create(context) {
return {
Identifier(node) {
if (node.name === "foo") {
context.report({
node,
messageId: "avoidName",
data: {
name: "foo",
}
});
}
}
};
}
};
And this is the ESLint package's index.js file itself, illustrating how do I export them:
const path = require('path');
const requireIndex = require('requireindex');
module.exports.rules = requireIndex(path.join(__dirname, 'rules'));
Project overview: https://i.stack.imgur.com/hLKcH.png
I'm desperately trying to make my NuxtJS app work with IE11. I implemented babel config in many ways to build a compatible version but I still have spread operators in built pages files, as if Babel didn't transform Nuxt code.
Here is my config:
nuxt.config.js
const pkg = require('./package')
const path = require('path');
module.exports = {
mode: 'universal',
// ...
build: {
babel: {
babelrc: true
},
extend(config, ctx) {
config.resolve.modules.push(path.resolve(__dirname, 'assets'));
const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
svgRule.test = /\.(png|jpe?g|gif|webp)$/;
config.module.rules.push({
test: /\.svg$/,
loader: 'vue-svg-loader',
}, {
test: /\.js$/,
loader: 'babel-loader'
})
}
}
}
.babelrc
{
"presets": [["#babel/preset-env", { "modules": false }]],
"plugins": [
"#babel/transform-runtime",
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-transform-spread",
"#babel/plugin-proposal-object-rest-spread"
],
"env": {
"test": {
"presets": [["#babel/preset-env", { "targets": { "node": "current" } }]]
}
}
}
.browserslistrc
# Browsers that we support
>0.2%
not dead
not ie < 11
not op_mini all
Despite that config, I still see some spread operators used in Nuxt built pages, like the following generated by nuxt:
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["pages/events/_slug.pages/index"],{
/***/ "./assets/svg/events/market.svg":
/*!**************************************!*\
!*** ./assets/svg/events/market.svg ***!
\**************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony default export */ __webpack_exports__["default"] = ({
functional: true,
render(_h, _vm) {
const { _c, _v, data, children = [] } = _vm;
const {
class: classNames,
staticClass,
style,
staticStyle,
attrs = {},
...rest
} = data;
I searched from some time across different issues about NuxtJS and Babel, but Nuxt claims that it works with IE9 without extra Babel configuration, which is not the case here. I'd like to understand why the code is not transpiled the right way.
I ran into a similar issue: A Nuxt app wouldn't work in the Edge browser because of spread operators in #nuxtjs/axios and bootstrap-vue. I did find a solution.
The build property in nuxt.config.js should be defined as follows:
build: {
babel: {
babelrc: true,
configFile: './babel.config.js'
},
transpile: [ '#nuxtjs/axios', 'bootstrap-vue' ],
// Other config
}
The transpile property is key here. Internally, Nuxt defines an exclude for babel-loader that ignores everything in node_modules, unless it's in transpile.
Using babel.config.js also appears to matter, and the official Babel documentation says you should use it if you want to process node_modules.
babel.config.js:
module.exports = function (api) {
api.cache(true);
return {
sourceType: 'unambiguous',
presets: ['#nuxt/babel-preset-app'],
plugins: ['#babel/plugin-proposal-object-rest-spread']
};
}
You don't need include or exclude here, as it's taken care of by Nuxt, as noted.
I'm trying to figure out whether or not webpack can do something like this. I have some code that I want to be bundled for a specific device. So I created a ViewFactories.ios.tsx and I also have ViewFactories.tsx. The problem i'm encountering is that the if I ignore the .ios.tsx in the loader test, it still gets bundled. I'm using the ignore-bundler plugin to ignore the .ios.tsx files, but the reference is just empty. ie:
/** still getting loaded here: **/
const ViewFactories_ios_1 = __importDefault(__webpack_require__(/*! ./ViewFactories.ios */ "./build/app/src/modules/layouts/factories/ViewFactories.ios.tsx"));
/*** the referenced section, but blank now ***/
/***/ "./build/app/src/modules/layouts/factories/ViewFactories.ios.tsx":
/*!***********************************************************************!*\
!*** ./build/app/src/modules/layouts/factories/ViewFactories.ios.tsx ***!
\***********************************************************************/
/*! dynamic exports provided */
/*! all exports used */
/***/ (function(module, exports) {
/***/ }),
What I really want is the reference to ViewFactories.tsx instead of ViewFactories.ios.tsx.
Is there some sort of dependency graph in webpack that I can access to tell the loader to use the default instead of the .ios.tsx?
My webpack config:
{
test: (modulePath) => {
if (/\.ios\./.test(modulePath)) {
console.log(modulePath);
return false;
}
return /\.tsx?$/.test(modulePath);
},
loader: "awesome-typescript-loader",
options: {
configFileName: 'tsconfig.web.json',
transpileOnly: true,
errorsAsWarnings: true,
}
},
{
test: (modulePath) => {
if (/\.ios\./.test(modulePath)) {
console.log('Ignored: ', modulePath);
return true;
}
return false;
},
loader: 'ignore-loader'
},
Just build two bundles, with shared config options for whatever is the same?
// webpack.config.js for two different bundles
let sharedModuleDef = {
rules: ...
}
let sharedPlugins = ...
let iosBundle = {
entry: "src/ios.entry.js",
output: {
path: ...
filename: "ios.bundle.js"
},
module: sharedModuleDef,
...
};
let everythingElse = {
entry: "src/main.entry.js",
output: {
path: ...
filename: "standard.bundle.js"
},
module: sharedModuleDef,
...
};
module.exports = [iosBundle, everythingElse];
Vue Cli defaults to file-loader for SVG assets, but I want to use svg-sprite-loader (as well as a few others) instead.
I updated the vue.config.js file to do this and it still seems to use file-loader. Almost as though it's not picking up my config at all.
vue.config.js
module.exports = {
configureWebpack: {
module: {
rules: [
{
test: /\.(svg)(\?.*)?$/,
use: [
{
loader: 'svg-sprite-loader',
options: {
name: '[name]-[hash:7]',
prefixize: true
}
},
'svg-fill-loader',
'svgo-loader'
]
}
]
}
}
}
Is there anything wrong with my setup?
I'm still getting SVG files imported into my component as a URL string / path when it should be an object with properties.
Many thanks.
This took me a while to find a work around. Basically you need to stop file-loader matching on .svg. The best way I have found to do this is using chainWebpack and returning false from the test method on file-loader. I have included my working config.
module.exports = {
lintOnSave: false,
configureWebpack: {
module: {
rules: [
{
test: /\.(svg)(\?.*)?$/,
use: [
{
loader: 'svg-inline-loader',
options: {
limit: 10000,
name: 'assets/img/[name].[hash:7].[ext]'
}
}
]
}
]
}
},
chainWebpack: config => {
config.module
.rule('svg')
.test(() => false)
.use('file-loader')
}
}
The Webpack docs for Vue CLI 3.0 beta got updated with an example on how to replace an existing Base Loader. For svg-sprite-loader this means that you'll have to add the following configuration to your vue.config.js:
chainWebpack: config => {
config.module
.rule('svg')
.use('file-loader')
.loader('svg-sprite-loader')
}
I'm using Vue CLI 3.0.3 and this config works for me 😉
const path = require('path');
const glob = require('glob');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
module.exports = {
lintOnSave: false,
configureWebpack: {
plugins: [
new SpriteLoaderPlugin()
]
},
chainWebpack: config => {
config.module.rules.delete('svg');
config
.entry('app')
.clear()
.add(path.resolve(__dirname, './src/main.ts'))
config
.entry('sprite')
.add(...glob.sync(path.resolve(__dirname, `./src/assets/icons/*.svg`)));
config.module.rule('svg')
.test(/\.(svg)(\?.*)?$/)
.use('file-loader')
.loader('svg-sprite-loader')
.options({
extract: true,
spriteFilename: 'icons.svg'
})
}
};
Vue CLI docs for version 3.x in webpack section suggests to use something like this:
// vue.config.js
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
// clear all existing loaders.
// if you don't do this, the loader below will be appended to
// existing loaders of the rule.
svgRule.uses.clear()
// add replacement loader(s)
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
}
}
Even vue-svg-loader configuration guide suggests same approach.
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
svgRule.clear()
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
}
}