How do I include 'fs' modules in Sapper? - config

I am working on a Sapper project, as it seemed neat for a little project I wanted to get up and running quickly. That's not be easy and I'm now having trouble running scripts from my Sapper project that include the built-in 'fs' modules.
I'm trying to build a character generator. I have built a script that will do this but I'd like to be able to save my generated characters as JSON files then read them in later. Reading in is easy, writing doesn't seem to be listed anywhere obvious. The best I have is trying to get the built in plugins to function to allow me access to fs modules but my research on this is spotty and not helping. Trying to get rollup to help doesn't appear to work and I am unable to find an acceptable alternative.
Whenever I run the project, it just says that it can't resolve it.
Could not load fs (imported by E:\Software Projects\Javascript\Io-Generator\src\routes\generator\generator.js): ENOENT: no such file or directory, open 'E:\Software Projects\Javascript\Io-Generator\fs'
Nothing I do seems to help. Please can someone explain what I'm missing here? Am I using Sapper wrong? Am I missing something in rollup here? Is there an alternative I'm missing?
My roll-up config if it helps:
client: {
input: config.client.input(),
output: config.client.output(),
plugins: [
replace({
'process.browser': true,
'process.env.NODE_ENV': JSON.stringify(mode)
}),
svelte({
dev,
hydratable: true,
emitCss: true
}),
resolve({
browser: true,
preferBuiltins: true,
dedupe
}),
commonjs( {
browser: true
} ),
globals(),
builtins( {
fs: true
} ),
json(),
legacy && babel({
extensions: ['.js', '.mjs', '.html', '.svelte'],
runtimeHelpers: true,
exclude: ['node_modules/#babel/**'],
presets: [
['#babel/preset-env', {
targets: '> 0.25%, not dead'
}]
],
plugins: [
'#babel/plugin-syntax-dynamic-import',
['#babel/plugin-transform-runtime', {
useESModules: true
}]
]
}),
!dev && terser({
module: true
})
],
onwarn,
},
server: {
input: config.server.input(),
output: config.server.output(),
plugins: [
replace({
'process.browser': false,
'process.env.NODE_ENV': JSON.stringify(mode)
}),
svelte({
generate: 'ssr',
dev
}),
resolve({
browser: false,
preferBuiltins: true,
dedupe
}),
commonjs(),
builtins( {
fs: true
} ),
json()
],
external: Object.keys(pkg.dependencies).concat(
require('module').builtinModules || Object.keys(process.binding('natives'))
),
onwarn,
},
serviceworker: {
input: config.serviceworker.input(),
output: config.serviceworker.output(),
plugins: [
resolve( {
browser: false,
preferBuiltins: true
} ),
replace({
'process.browser': true,
'process.env.NODE_ENV': JSON.stringify(mode)
}),
commonjs(),
builtins( {
fs: true
} ),
json(),
!dev && terser()
],
onwarn,
}
};```

So, I went an restarted my project from a fresh project. Aaaaand it was fine. It's working fine. It's possible that I really screwed up my project trying out multiple different things to get them working, causing some serious damage. I'll need to be more careful in future.

Related

Nuxt.js returns undefined for custom plugin

I wanted to create a custom plugin for a local databaase in Nuxt.js, after I was done with the code I registered it in nuxt.config.js and it didn't work. So I've tried the example code on docs to see what I was doing wrong, and the thing is, example code didn't work too. Here is how I registered it:
plugins/hello.js
export default ({ app }, inject) => {
inject("hello", msg => console.log(`Hello ${msg}!`));
};
nuxt.config.js
module.exports = {
ssr: false,
target: "static",
head: {
title: "project-title",
meta: [{ charset: "utf-8" }],
},
loading: false,
plugins: [{ ssr: true, src: "#/plugins/icons.js" }, "#/plugins/hello.js"],
modules: ["#nuxtjs/axios", "#nuxtjs/auth-next"],
}
Whenever I try to use this.$hello("something"), Nuxt returns this.$hello is not a function
Hmm, got it. After deleting and reinstalling node_modules it's resolved, then I tried changing the name of the plugin file, after then build failed from ./node_modules/#nuxt/webpack/node_modules/babel-loader/lib/index.js. After reinstalling packages again (deleted .nuxt, node_modules and lock file) issue is resolved.

Unable to get eslint-plugin-graphql to notice deprecated fields

I can't get eslint-plugin-graphql to notice a deprecated field (look for "deprecationReason": "Use localizedDescription") when I use it in a query file.
When running yarn lint it does not find anything wrong. Tried to add the rules to .eslintrc.js:
'graphql/template-strings': [
'error',
{
env: 'literal',
// eslint-disable-next-line global-require
schemaJson: require('./graphql.schema.json'),
},
],
'graphql/no-deprecated-fields': [
'error',
{
env: 'relay',
// eslint-disable-next-line global-require
schemaJson: require('./graphql.schema.json'),
},
],
'graphql/no-deprecated-fields': [
'error',
{
env: 'apollo',
// eslint-disable-next-line global-require
schemaJson: require('./graphql.schema.json'),
},
],
'graphql/no-deprecated-fields': [
'error',
{
env: 'literal',
// eslint-disable-next-line global-require
schemaJson: require('./graphql.schema.json'),
},
],
But it won't find the deprecated field.
It must be vue related because if I run eslint myself it will give me the error:
myComputer$ node ./node_modules/eslint/bin/eslint.js ./src/components/Cart.gql
/Path/to/project/src/components/Cart.gql
48:7 error The field ShippingMethod.description is deprecated. Use localizedDescription graphql/no-deprecated-fields
✖ 1 problem (1 error, 0 warnings)
I was also not able to run the linter directly and have it detect errors in both js and gql files. But that may be a different question.

Cannot find module '#/assets/<file-name-here>.svg'. #vue/cli Version: 4.2.3 and 4.3.1

General jist:
import Image from '#/assets/default-profile-picture.svg'
//ERROR: Cannot find module '#/assets/default-profile-picture.svg'.Vetur(2307)
I have spent the better part of today trying to find a solution to this. I know there are a lot of other posts like this one, but they are all outdated (all over a year old).
I've just generated a clean Vue CLI app, and still have the same issue.
I'm using Vue CLI Version 4.2.3, and just attempted using Vue CLI Version 4.3.1, but ran into the same issue.
I have checked that the file is in assets.
I have checked that the filename is spelled correctly.
I have a feeling this is a webpack issue, as require() would not work when called using typescript.
I have tried creating vue.config.js and manually setting the path for assets.
Project setup configuration:
Features: Babel, TS, Router, ESLint
not class-style syntax
Babel used alongside Typescript
No history mode for router
eslint with error prevention only
Lint on save
Configs placed in package.json.
Error in Component.vue
<script lang="ts">
import Vue from 'vue'
/* Cannot find module '#/assets/default-profile-picture.svg'.Vetur(2307) */
import Image from '#/assets/default-profile-picture.svg'
export default Vue.extend({
components: {
},
props: [
'employeeImage',
'employeeName',
'employeeAge',
'employeeSalary'
],
data () {
return {
marked: false,
result: [],
name: this.employeeName,
age: this.employeeAge,
salary: this.employeeSalary
}
},
computed: {
compClasses: function () {
return {
marked: this.marked
}
},
imageDefault: function () {
if (this.employeeImage === '') {
console.log('employee image empty: ' + this.employeeImage)
return '#/assets/default-profile-picture.svg'
} else {
console.log('employee image set: ' + this.employeeImage)
return this.employeeImage
}
}
}
})
</script>
Typescript Config
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"#/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"/src/**/*.*",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
What am I doing wrong?
Thanks in advance!
Please keep this in mind, that this answer is not a solution but more like a work-around for this issue by the time this question has been asked/answered for vue-svg-loader(#vue/cli Version: 4.2.3 and 4.3.1).
You can use absolute path instead of using # to reference the file when you want to import .vue components. Here is an example:
Instead of this:
Read more about this issue and any possible solutions on official repository for this issue on GitHub:
Typescript Cannot find module '#/assets/svg/register.svg?inline' #92
Typescript does not support svg files.
Create a svg.d.ts file in your project source folder with the following content:
declare module '*.svg';
and restart your editor

responsive-loader with nuxt.js

I want to integrate responsive-loader into my Nuxt.js project which runs in SPA mode. (Optional I want to add Vuetify Progressive Image support also).
It will be a static hosting with Netlify.
Versions:
"nuxt": "^2.3.4"
"responsive-loader": "^1.2.0"
"sharp": "^0.21.1"
I found some solutions how to do it (https://stackoverflow.com/a/51982357/8804871) but this is not working for me.
When I run npm run build
I get an error message: "TypeError: Cannot set property 'exclude' of undefined"
My build section looks the following:
build: {
transpile: [/^vuetify/],
plugins: [
new VuetifyLoaderPlugin()
],
extractCSS: true,
/*
** Run ESLint on save
*/
extend(config, { isDev, isClient, isServer }) {
// Default block
if (isDev && isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
if (isServer) {
config.externals = [
nodeExternals({
whitelist: [/^vuetify/]
})
]
}
// Default block end
// here I tell webpack not to include jpgs and pngs
// as base64 as an inline image
config.module.rules.find(
rule => rule.loader === "url-loader"
).exclude = /\.(jpe?g|png)$/;
/*
** Configure responsive-loader
*/
config.module.rules.push({
test: /\.(jpe?g|png)$/i,
loader: "responsive-loader",
options: {
min: 350,
max: 2800,
steps: 7,
placeholder: false,
quality: 60,
adapter: require("responsive-loader/sharp")
}
});
}
}
The error is probably found in this section:
config.module.rules.find(
rule => rule.loader === "url-loader"
).exclude = /\.(jpe?g|png)$/;
Like said I get this error message: "TypeError: Cannot set property 'exclude' of undefined".
I run this project along with vuetify. I also would like to enable the Progressive image support together with responsive loader. Does anybody know how to setup both rules together?
https://github.com/vuetifyjs/vuetify-loader#progressive-images
The easiest way to integrate responsive-loader into a Nuxt.js project is to use this module: https://www.npmjs.com/package/nuxt-responsive-loader
Disclaimer: I created the module
The problem with your config that it relies on rule.loader property but rule can be defined in use or oneOf config sections as well.
Another one problem is that nuxt internal config has several rules with url-loader(for images, videos, fonts ...).
In your case the rule, you tried to find, has use section and url-loader is defined there, that's why your find function found nothing and threw this error:
{
"test": /\.(png|jpe?g|gif|svg|webp)$/,
"use": [{
"loader": "url-loader",
"options": {
"limit": 1000,
"name": "img/[hash:7].[ext]"
}
}]
}
About responsive-loader, you should remove extensions you want to process with responsive-loader from url-loader rule to avoid unexpected behavior and conflicts, here is extend function working example:
extend(config, ctx) {
let imgTest = '/\\.(png|jpe?g|gif|svg|webp)$/';
// find by reg ex string to not rely on rule structure
let urlRule = config.module.rules.find(r => r.test.toString() === imgTest);
// you can use also "oneOf" section and define both loaders there.
// removed images from url-loader test
urlRule.test = /\.(svg|webp)$/;
config.module.rules.push({
test: /\.(png|jpe?g|gif)$/,
loader: "responsive-loader",
options: {
// place generated images to the same place as url-loader
name: "img/[hash:7]-[width].[ext]",
min: 350,
max: 2800,
steps: 7,
placeholder: false,
quality: 60,
adapter: require("responsive-loader/sharp")
}
})
}
Yes, it looks dirty, but I think it's only way for now to change some loader.
What about vuetify - I think both loaders will conflict with each other and probably the solution is to use single loader that will work with your images.
Hope it helps.
Update for Nuxt >= 2.4.0:
They modified the rules array please update the following line:
let imgTest = '/\\.(png|jpe?g|gif|svg|webp)$/i';
Then the code should work normally again.

How to workaround the "Unexpected Token Operator (>)" error when packaging a React app?

I am having some problems building the distributable package for a React app.
I'm trying to execute the following sentence:
rimraf dist && env-cmd .env cross-env NODE_ENV=production webpack -p --config ./config/webpack/prod.js
And receiving this error:
ERROR in a86e50ffd4893c44fdfd.app.js from UglifyJs Unexpected token:
operator (>) [a86e50ffd4893c44fdfd.app.js:10679,43]
The line indicated in that trace corresponds to one of the libraries being loaded as dependencies, and not to the actual code of my app. This is the line itself (line 10679 corresponds to the declaration of the const method with the arrow function):
const DEFAULT_DISPLAY_LABEL_FOR_NULL_VALUES = '';
/* unused harmony export DEFAULT_DISPLAY_LABEL_FOR_NULL_VALUES */
const getAllColumnLabels = (columnLabels) => {
const columnNames = [];
columnLabels.forEach((value) => {
columnNames.push(value.label);
});
return columnNames;
};
At first I thought it could be related to Babel config, but it is identical to another project which is building correctly. The content of my .babelrc file is shown below, loaded using babel-preset-env:
{
"presets": [
[
"env", {
"modules": false,
"targets": {
"browsers": [
"Chrome >= 52",
"FireFox >= 44",
"Safari >= 7",
"Explorer 11",
"last 4 Edge versions"
]
},
"useBuiltIns": true
}
]
]
}
An additional test to rule out some possibilities has been done using the default presets for Babel, though no success was achieved with this test.
{
"presets": [
[
"env",
{
"modules": false
}
]
]
}
The settings in tsconfig.json could also be of interest, so i'm showing them here even though they also are identical to the ones in this another project mentioned above, which builds correctly:
{
"compilerOptions": {
"target": "es6",
"module": "es6",
"lib": ["dom", "es2017"],
"moduleResolution": "node",
"declaration": false,
"noImplicitAny": false,
"sourceMap": true,
"jsx": "react",
"noLib": false,
"allowJs": true,
"suppressImplicitAnyIndexErrors": true,
"skipLibCheck": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
},
"compileOnSave": true,
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
I've tried to delete node_modules and re-install the dependencies, also played setting uglify to false in the env for Babelrc, but surprisingly (at least, to me!) it didnt help.
There is a thread in the webpack-contrib Github site which is marked as closed but I didnt find anything that helped me.
Any ideas? I have some experience with npm but this issue certainly is blocking me.
Thanks!
Updating webpack to version 4 (currently 4.17) solved the problem. A few other dependencies needed to be updated to work properly with webpack 4, most importantly the Extract Text Webpack Plugin hasn't at this moment a stable release that works with webpack4, but the 4.0.0-beta works around the issue and may be used until a better replacement is found.