"You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file". Electron+Vue - vue.js

I am trying to use the npm package "Typeorm" in my Electron + Vue project, but when I run it I have this error:
Module parse failed: Unexpected character '​' (2:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| import { EntitySchema } from "typeorm"
> ​
| export default new EntitySchema({
| name: "Post", // Will use table name `post` as default behaviour.
But I don't even have a webpack.config.js in my project. Not even inside files from frameworks that i'm using. So I can't follow the tips of this https://webpack.js.org/concepts#loaders.
The file that contains this import:
Category.js
import { EntitySchema } from "typeorm"
export default new EntitySchema({
name: "Category", // Will use table name `category` as default behaviour.
tableName: "categories", // Optional: Provide `tableName` property to override the default behaviour for table name.
columns: {
id: {
primary: true,
type: "int",
generated: true,
},
name: {
type: "varchar",
},
},
})
This is my Babel.config:
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset'
]
}
To try to make it work, in my vue.config.js I added this "transpileDependecies", as suggested in #vue/cli-plugin-babel/preset . But it stills the same error.
vue.config.js
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: [
'typeorm'
],
configureWebpack: {
devtool: 'source-map',
},
pluginOptions: {
vuetify: {
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vuetify-loader
}
}
})
Other similar questions did not help..

Related

Changes in yaml files displays only after restart metro server

I am using babel-plugin-content-transformer library to use yaml files. I need to use them instead of json in react-i18next localisation library. It works fine but there is one issue: when i change some translation in .yml file the changes displays only after I restart metro server. Reload also doesn't works, I see no changes after I pressed 'r' to reload server. To see changes I need to stop and after that run server again.
My babel.config.js is
module.exports = function (api) {
const presets = [['module:metro-react-native-babel-preset']]
const plugins = [
['module-resolver', {
root: ['./'],
extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
alias: {
'#bluecentury': './src',
}
}],
['module:react-native-dotenv', {
'moduleName': '#vemasys/env',
}],
['react-native-reanimated/plugin'],
['content-transformer', {
transformers: [{
file: /\.ya?ml$/,
format: 'yaml'
}]
}]
]
api.cache(false)
return {
presets,
plugins
}
}
my i18n.ts is
import i18n from 'i18next'
import {initReactI18next} from 'react-i18next'
import translationEN from './enyaml.yml'
// import translationEN from './en.json'
const resources = {
en: {
translation: translationEN,
},
}
i18n.use(initReactI18next).init({
resources,
lng: 'en',
fallbackLng: 'en',
interpolation: {
escapeValue: false,
},
})
When I'm using en.json everything works fine.

Add script into HTML using vite and vue 3

I have one js file which needs to be put in the public directory and needs to add it in the final production build as a text/javascript.
I have checked the options in vite config but couldn't find anything useful. The files I add contain a global JSON object and can be accessed directly.
To achieve this, I tried this solution.
vite.config.ts
import { fileURLToPath, URL } from "url";
import path from 'path';
// import test from "./src/assets/test.js"
import test from "./public/test.js"
import { defineConfig , loadEnv} from "vite";
import vue from "#vitejs/plugin-vue";
import { loadingScript } from 'vite-plugin-loading-script'
export default defineConfig(({ command, mode }) => {
// Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
const env = loadEnv(mode, process.cwd(), '')
return {
// vite config
define: {
__APP_ENV__: JSON.stringify(env.VITE_REDIRECT_URL),
__TEST__: test,
},
plugins: [vue()],
server: {
hmr: {
overlay: false,
},
},
resolve: {
alias: {
"#": fileURLToPath(new URL("./src", import.meta.url)),
},
},
build: {
// rollupOptions: {
// external: ['__APP_ENV__'],
// output: {
// globals: {
// __APP_ENV__: JSON.stringify(env.VITE_REDIRECT_URL),
// }
// }
// }
}
}
});
test.js
export default {
REDIRECT_URL: "https://example.com/",
API_URL: "https://example.com/",
};
with the above changes, I got the console.log('__TEST__', __TEST__) as expected JSON object but it doesn't work with the production build.
maybe you can try including the js file to the html in the public directory

Internal server error: Cannot read property 'length' of undefined

Getting an error
[vite] Internal server error: Cannot read property 'length' of undefined
This is happening while trying to run my vue project using vite.
Below is the error stack:
Build failed with 1 error: node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:59574:34: ERROR: [plugin: vite:dep-scan] Cannot read property 'length' of undefined 2:44:29 PM [vite] Internal server error: Cannot read property 'length' of undefined at matches (/Users/pandocorp/Desktop/pando/codes/pando-app/frontend/shipper/node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:59574:35) at /Users/pandocorp/Desktop/pando/codes/pando-app/frontend/shipper/node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:59633:58 at Array.find () at Context.resolveId (/Users/pandocorp/Desktop/pando/codes/pando-app/frontend/shipper/node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:59633:42) at Object.resolveId (/Users/pandocorp/Desktop/pando/codes/pando-app/frontend/shipper/node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:36609:55) at processTicksAndRejections (internal/process/task_queues.js:95:5) at async ModuleGraph.resolveUrl (/Users/pandocorp/Desktop/pando/codes/pando-app/frontend/shipper/node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:56244:26) at async ModuleGraph.getModuleByUrl (/Users/pandocorp/Desktop/pando/codes/pando-app/frontend/shipper/node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:56124:23) at async doTransform (/Users/pandocorp/Desktop/pando/codes/pando-app/frontend/shipper/node_modules/vite/dist/node/chunks/dep-27bc1ab8.js:55582:20)
My vite.config.js
import { defineConfig } from 'vite';
import { createVuePlugin } from 'vite-plugin-vue2';
const config = require('./config');
const path = require('path');
export default defineConfig({
plugins: [createVuePlugin()],
server: {
port: 8080,
},
resolve: {
alias: [
{
'#': path.resolve(__dirname, './src'),
},
{
'#common': path.resolve(__dirname, '../common-v2'),
},
// {
// find: path.resolve(__dirname, '../static'),
// replacement: config.dev.assetsSubDirectory,
// ignore: ['.'],
// },
// {
// find: path.resolve(__dirname, '../firebase-messaging-sw.js'),
// replacement: 'firebase-messaging-sw.js',
// ignore: ['.'],
// },
],
},
build: {
chunkSizeWarningLimit: 600,
cssCodeSplit: false,
},
});
When I encountered this error, adding the following to vite.config.js seemed to resolve it.
resolve: {
alias: [
{
find: /^~(.*)$/,
replacement: 'node_modules/$1',
},
],
},
I had the same issue with a brand new Vite project. I don't know if this is your case, but I created this new project under a directory of another project like so:
/some/path/my-project <- "parent project"
/some/path/my-project/... <- other project files
/some/path/my-project/node_modules
/some/path/my-project/... <- other project files
/some/path/my-project/brand-new-vite-project <--- THIS ONE!
This nesting seems to generate the issue, because I moved the brand new project elsewhere and everything worked as expected.
Same problem encountered while getting throug Amplify "getting started" (which requires a new alias)
The solution for me was to rewrite the config as follows
export default defineConfig({
plugins: [vue()],
resolve: {
alias: [
{
"./runtimeConfig": "./runtimeConfig.browser",
"#": fileURLToPath(new URL("./src", import.meta.url)),
},
],
},
});

ESM library generated with rollup-plugin-postcss throws Cannot find module '../node_modules/style-inject/dist/style-inject.es.js'

We are maintaining an internal library which is exporting ESM modules using Rollup. We have just recently switched to using CSS modules, which we have set with rollup-plugin-postcss. We want to inject these styles into the head rather than have an external file.
Our built bundle generates the ESM file with:
import styleInject from '../node_modules/style-inject/dist/style-inject.es.js';
Our consuming library then fails with
Uncaught Error: Cannot find module '../node_modules/style-inject/dist/style-inject.es.js'
I would expect the ESM export to import styleInject from 'style-inject' and style-inject to be included in the package-lock.json as a dependency. What is the correct way of using CSS Modules and injecting into the head for the consumer of a library?
rollup.config.js
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import babel from '#rollup/plugin-babel';
import json from '#rollup/plugin-json';
import postcss from 'rollup-plugin-postcss';
import pkg from './package.json';
import fg from 'fast-glob';
import path from 'path';
export default [
{
input: 'src/index.js',
external: external(),
output: [
{
name: '#my/packageName',
file: pkg.module,
format: 'es',
sourcemap: true,
},
],
plugins: [
{
name: 'watch-external',
async buildStart() {
const files = await fg(['src/index.d.ts', 'playground/**/*']);
for (let file of files) {
this.addWatchFile(path.resolve(file));
}
},
},
json(),
postcss({
modules: true,
}),
babel({
exclude: /node_modules/,
babelHelpers: 'runtime',
babelrc: false,
presets: [
[
'#babel/preset-env',
{
modules: false,
useBuiltIns: 'entry',
corejs: 3,
targets: {
ie: 11,
},
},
],
'#babel/preset-react',
],
plugins: [
'#babel/plugin-transform-runtime',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-export-namespace-from',
],
}),
commonjs(),
],
},
];
function external() {
const { dependencies = {}, peerDependencies = {} } = pkg;
const externals = [
...Object.keys(dependencies),
...Object.keys(peerDependencies),
];
return id =>
// match 'lodash' and 'lodash/fp/isEqual' for example
externals.some(dep => id === dep || id.startsWith(`${dep}/`));
}
There is a bug in the library where the import is relative rather than being the module name.
There is an open pr, but the library looks like it is no longer being maintained. There are two recommended solutions in the comments:
String replace the built output
Add a custom rollup plugin to do this
This is not a bug at all. It works properly because stylesInject is just a function from 'styles-inject' package, so we can allow it to be bundled. But it is not bundled because most likely you have this setting in your rollup.config.js:
external: [
/node_modules/
]
So, replace it with a code bellow and it will work:
external: (id) => {
if (/style-inject/.test(id)) return false;
if (/node_modules/.test(id)) return true;
return false;
},
also, you can write a regexp for it instead
You need to do 2 things:
Add style-inject dependency in package.json
"dependencies": {
"style-inject": "^0.3.0"
},
Add following plugin to rollup.config.js
const plugins = [
...
{
/**
* - https://github.com/egoist/rollup-plugin-postcss/issues/381#issuecomment-880771065
* - https://lightrun.com/answers/egoist-rollup-plugin-postcss-esm-library-generated-with-rollup-plugin-postcss-throws-cannot-find-module-node_modulesstyle-in
*/
name: 'Custom Rollup Plugin`',
generateBundle: (options, bundle) => {
Object.entries(bundle).forEach((entry) => {
// early return if the file we're currently looking at doesn't need to be acted upon by this plugin
if (!entry[0].match(/.*(.scss.js)$/)) {
return;
}
// this line only runs for .scss.js files, which were generated by the postcss plugin.
// depending on the use-case, the relative path to style-inject might need to change
bundle[entry[0]].code = entry[1].code.replace(
/\.\.?\/[^\n"?:*<>|]+\/style-inject\/dist\/style-inject.es.js/g,
'style-inject',
);
});
},
}
];
References:
https://github.com/egoist/rollup-plugin-postcss/issues/381#issuecomment-880771065
https://lightrun.com/answers/egoist-rollup-plugin-postcss-esm-library-generated-with-rollup-plugin-postcss-throws-cannot-find-module-node_modulesstyle-in

Webpack using wrong node_modules folder

I have a vue client project that uses a vue library project (the vue library project is also using some 3rd party packages like vue-material).
They are linked via the client project's Package.json like this "lib": "file:../lib" and I am importing components in the client project using import Comp from "lib/src/components/Comp";
The problem is that when I build the client project using Webpack, the files in my library use lib/node_modules/vue instead of node_modules/vue which causes double vue instancing.
Anyone has any idea why when I am using webpack build from the client folder, it looks for vue package in my library folder? and is there a way to get around that?
My webpack.config
"use strict";
const path = require("path");
const utils = require("./utils");
const config = require("../config");
const vueLoaderConfig = require("./vue-loader.conf");
function resolve(dir) {
return path.join(__dirname, "..", dir);
}
module.exports = {
entry: {
app: ["babel-polyfill", "./src/main.js"]
},
output: {
path: config.build.assetsRoot,
filename: "[name].js",
publicPath: process.env.NODE_ENV === "production" ? config.build.assetsPublicPath : config.dev.assetsPublicPath
},
resolve: {
extensions: [".js", ".vue", ".json"],
alias: {
vue$: "vue/dist/vue.esm.js",
"#": resolve("src"),
src: resolve("src"),
assets: resolve("src/assets"),
components: resolve("src/components"),
utilities: resolve("src/utilities"),
directives: resolve("src/directives"),
plugins: resolve("src/plugins"),
data: resolve("src/data"),
"vuex-store": resolve("src/store"),
"lib": resolve("node_modules/lib")
}
},
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: "eslint-loader",
enforce: "pre",
include: [resolve("src")],
options: {
formatter: require("eslint-friendly-formatter")
}
},
{
test: /\.vue$/,
loader: "vue-loader",
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: "babel-loader",
include: [resolve("src"), resolve("../lib/src")]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 10000,
name: utils.assetsPath("img/[name].[hash:7].[ext]")
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 10000,
name: utils.assetsPath("media/[name].[hash:7].[ext]")
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: "base64-font-loader",
options: {
limit: 10000,
name: utils.assetsPath("fonts/[name].[hash:7].[ext]")
}
},
{
test: /\.ico$/,
loader: "file-loader?name=[name].[ext]"
}
]
}
};
My client's main entry
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
// Core Imports
import Vue from 'vue'
import App from './App'
// Plugins
import { ComponentsPlugin } from "lib/src/components";
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
As I ran out of solutions to this problem I decided to debug webpack's compiler.
It seems webpack uses a library called 'enhanced-resolve' (We actually send parameters to that library in our webpack's resolve:{} section). And using the resolve.alias property we can redirect any require to any folder we want.
So to redirect any require("vue") to my own vue.esm.js, all I need is to add an entry like this (I originally had that line but it was pointing to a relative path rather than an absolute path):
resolve: {
alias: {
vue$: resolve("node_modules/vue/dist/vue.esm.js"),
}
}
Note the $ at the end of the library name, It signals enhanced-resolve that the package only has 1 module so any require whos name is "vue" or a sub-directory of "vue" should be parsed using the alias.
Enhanced-Resolve - ResolverFactory.js
if(/\$$/.test(alias)) {
onlyModule = true;
....
}
Enhanced-Resolve - AliasPlugin.js
// InnerRequest is the path (vue/dist/vue.esm.js)
// name is the alias name without the $ (vue)
if(innerRequest === name || (!onlyModule && startsWith(innerRequest, name + "/"))) {
continue resolving....
}