React+Typescript+Webpack4: Cannot find module '***.json' - webpack-4

I am trying to import the data from a .json file in a .tsx using following:
import data from "data/mockup.json"
but I got the error
Cannot find module 'data/mockup.json'
My webpack config looks like this:
const babelLoader = {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: [
["#babel/preset-env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
},
"modules": true
}]
]
}
};
module.exports = {
entry: {...},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
alias: {
data: path.resolve(__dirname, 'src/app/data')
}
},
output: {...},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
babelLoader,
{
loader: 'ts-loader'
}
]
},
{
test: /\.js$/,
exclude: /node_modules\/(?!(dom7|swiper)\/).*/,
use: [
babelLoader
]
}
]
},
...
}
enter code here
I think the .json is built in webpack4 by default so there may be something wrong with my webpack config?
Version used:
webpack: v4.4.1
typescript: 2.7.2

declare module in d.ts file
declare module "*.json"
Add a field in tsconfig.json in compiler options
"typeRoots": [ "node_modules/#types", "./typings.d.ts" ],
Now import into file (.tsx)
import * as data from "./dat/data.json";
Webpack#4.4.1 and Typescript#2.7.2
Hope this helps!!!
Ref1: https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
Ref2: https://github.com/Microsoft/TypeScript-React-Starter/issues/12

Although answers are helpful to load the JSON file as a module, they are limited in many aspects
First: the typescript can load by default JSON files, you only need to add into tsconfig.json below line:
{
...
"resolveJsonModule": true,
...
}
second: the suggested solution will enable implicitly for type check and auto-completion
P.S. the attached image is from a tutorial that talks about the same subject click here to check more

Personnaly, uncommenting :
"allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
in the file tsconfig.json did the trick.
I found the hint here.

Related

Unable to instrument expo app with istanbul or cypress/instrument

I have been trying this for a while now, without success.
I have an expo app and I am using cypress to test some use cases using the web version of the app (generated by expo).
However, I would like to generate some code coverage as well. I have read the official documentation for it, that recommends to babel-plugin-istanbul do to so, but it does not seem to work with expo.
I am not sure why this would not work.
Edit
I removed the files previously pointed here as they were not important.
Thanks for a wonderful documentation provided by a hero without a cape, I figured that my settings were wrong.
All I needed to do was:
install babel-plugin-istanbul
Update babel.config.js
module.exports = {
presets: ['babel-preset-expo'],
plugins: [
'istanbul',
[
'module-resolver',
{
root: ['.'],
extensions: [
'.js',
],
alias: {
'#': './',
},
},
],
],
};
update cypress/support/index.js
import '#cypress/code-coverage/support';
update cypress/plugins/index.js
module.exports = (on, config) => {
require('#cypress/code-coverage/task')(on, config);
// add other tasks to be registered here
// IMPORTANT to return the config object
// with the any changed environment variables
return config;
};
and voilĂ !

How do I solve this Apollo Control Cache error?

I am trying to set up my server side backend and I'm hitting this error:
node_modules/apollo-cache-control/dist/index.d.ts:24:9 - error TS2717: Subsequent property declarations must have the same type. Property 'cacheControl' must be of type 'ResolveInfoCacheControl', but here has type '{ setCacheHint: (hint: CacheHint) => void; cacheHint: CacheHint; }'.
24 cacheControl: {
~~~~~~~~~~~~
node_modules/#nestjs/graphql/node_modules/apollo-server-types/dist/index.d.ts:140:9
140 cacheControl: ResolveInfoCacheControl;
~~~~~~~~~~~~
'cacheControl' was also declared here.
I just found a fix for this, You have to add this to your tsconfig.json file:
"skipLibCheck": true
My tsconfig.json looks like:
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es2015",
"noImplicitAny": false,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "lib",
"baseUrl": "./",
"lib": ["es6", "esnext.asynciterable"],
"types": ["node"],
"skipLibCheck": true
},
"include": ["src/**/*"]
}
And also make sure to have all apollo packages to have same exact version.
Make sure all apollo packages (apollo-server, apollo-server-express, apollo-server-core) have the exact same version
In my case it was a bad import. I was importing import { VariableValues } from 'apollo-server-types/src' instead of import { VariableValues } from 'apollo-server-types'
I swear it was the auto-importer....

How to access Vuejs methods to test with Jest?

I have the following file: deposit-form.js.
With the following code:
new Vue({
el: '#app',
data: {
title: 'title',
depositForm: {
chosenMethod: 'online',
payMethods: [
{ text: 'Already paid via Venmo', value: 'venmo' },
{ text: 'Pay online', value: 'online' },
{ text: 'In-person payment', value: 'person' }
],
},
},
methods: {
submitDeposit: function() {
$.ajax({
url: 'http://localhost:8000/api/v1/deposit/',
type:'post',
data: $('#deposit-form').serialize(),
success: function() {
$('#content').fadeOut('slow', function() {
// Animation complete.
$('#msg-success').addClass('d-block');
});
},
error: function(e) {
console.log(e.responseText);
},
});
},
showFileName: function(event) {
var fileData = event.target.files[0];
var fileName = fileData.name;
$('#file-name').text('selected file: ' + fileName);
},
},
});
I'm having problems on how to setup Jest, how to import the VueJs functions inside 'methods' to make the tests with Jest.
How should be my code on the deposit-form.test.js ?
The first thing you need to do is export Vue app instance.
// deposit-form.js
import Vue from 'vue/dist/vue.common';
export default new Vue({
el: '#app',
data: {...},
...
});
Now you can use this code in your spec file. But now you need to have #app element before running tests. This can be done using the jest setup file. I will explain why it's needed. When you import your main file (deposit-form.js) into a test, an instance of Vue is created in your main file with new. Vue is trying to mount the application into #app element. But this element is not in your DOM. That is why you need to add this element just before running the tests.
In this file you also can import jQuery globally to use it in your tests without import separately.
// jest-env.js
import $ from 'jquery';
global.$ = $;
global.jQuery = $;
const mainAppElement = document.createElement('div');
mainAppElement.id = 'app';
document.body.appendChild(mainAppElement);
Jest setup file must be specified in the jest configuration section in package.json.
// package.json
{
...,
"dependencies": {
"jquery": "^3.3.1",
"vue": "^2.6.7"
},
"devDependencies": {
"#babel/core": "^7.0.0",
"#babel/plugin-transform-modules-commonjs": "^7.2.0",
"#babel/preset-env": "^7.3.4",
"#vue/test-utils": "^1.0.0-beta.29",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.1.0",
"babel-loader": "^8.0.5",
"babel-preset-vue": "^2.0.2",
"jest": "^24.1.0",
"vue-jest": "^3.0.3",
"vue-template-compiler": "^2.6.7",
"webpack": "^4.29.5",
"webpack-cli": "^3.2.3"
},
"scripts": {
"test": "./node_modules/.bin/jest --passWithNoTests",
"dev": "webpack --mode development --module-bind js=babel-loader",
"build": "webpack --mode production --module-bind js=babel-loader"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"setupFiles": [
"<rootDir>/jest-env.js"
]
}
}
Also, you probably need to configure Babel to use the features of ES6 in your projects and tests. This is not necessary if you follow the commonjs-style in your code. Basic .babelrc file contains next code:
// .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "entry",
"targets": {
"browsers": [
"last 2 versions"
]
}
}
],
"vue",
],
"plugins": [
"#babel/plugin-transform-modules-commonjs",
]
}
Now you can write your tests.
// deposit-form.test.js
import App from './deposit-form';
describe('Vue test sample.', () => {
afterEach(() => {
const mainElement = document.getElementById('app');
if (mainElement) {
mainElement.innerHTML = '';
}
});
it('Should mount to DOM.', () => {
// Next line is bad practice =)
expect(App._isMounted).toBeTruthy();
// You have access to your methods
App.submitDeposit();
});
});
My recommendation is to learn Vue Test Utils Guides and start to divide your code into components. With the current approach, you lose all the power of components and the ability to test vue-applications.
I updated my answer a bit. As I understood from the comment to the answer, you connect the libraries on the page as separate files. Here is my mistake. I didn't ask if the build system is being used. Code in my examples is written in the ECMA-2015 standard. But, unfortunately, browsers do not fully support it. You need an transpiler that converts our files into a format that is understandable for browsers. It sounds hard. But it's not a problem. I updated the contents of the file package.json in response. Now it only remains to create an input file for the assembly and run the assembly itself.
The input file is simple.
// index.js
import './deposit-form';
The build is started with the following commands from terminal.
# for development mode
$ yarn run dev
# or
$ npm run dev
# for production mode
$ yarn run build
# or
$ npm run build
The output file will be placed in the directory ./dist/. Now instead of separate files you need to connect only one. It contains all the necessary for the library and your code.
I used webpack to build. More information about it can be found in the documentation. Good example you can find in this article.

Webpack TypeScript and xgettext translations

I have a Django app and am using Django's i18n module to help translating my strings. For translating JavaScript, I run
python manage.py makemessages -d djangojs
which adds all marked strings to a .po file. This works quite well for all my boring .js files in my static folder. However, we are starting to use webpack to pack some typescript (.tsx files) into a bundle.js file. This file is copied to the static folder after building, so I expected Djangos makemessages to pick up the strings from it as well. However, it seems that the strings are not parsed correctly, because most of the code in bundle.js is simply strings wrapped in eval().
I believe this means that I need webpack to - in addition to the bundle.js file - create a .js file for each .tsx file without all of the eval() nonsense, so that django's makemessages can parse it properly. I have no idea how to do this, however. My current config looks like this
var path = require("path");
var WebpackShellPlugin = require('webpack-shell-plugin');
var config = {
entry: ["./src/App.tsx"],
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js"
},
devtool: 'source-map',
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/
},
{
test: /\.scss$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
}
]
},
plugins: [
new WebpackShellPlugin({
onBuildEnd:['./cp_to_static.sh'],
dev: false // Needed to trigger on npm run watch
})
]
};
module.exports = config;
So how can I make webpack spit out these files?
Is this the right thing to do, or is there a way to make Django parse bundle.js properly?
Turns out that all of the eval nonsense was generated by webpacks "watch" function. When simply running webpack for building the script, it works as expected

Custom build for Dojo 1.7.1 with Layer and CSS Optimization

With Dojo 1.6.x it was quite easy to create a custom build. In the end I only needed to include a dojo.js file, my application layer file and an optimized css file with all the styles. Simple and easy.
But with Dojo 1.7.x I don't get it. My goal is just to include an opmtimized dojo.js file, my application layer file with all my widgets and stuff and an optmized css file.
Here is my profile.js
var profile = {
releaseDir: "./release",
basePath: "..",
action: "release",
cssOptimize: "comments",
mini: true,
optimize: "closure",
layerOptimize: "closure",
stripConsole: "all",
selectorEngine: "acme",
packages:[
{
name: "dojo",
location: "./sources/dojo"
},
{
name: "dijit",
location: "./sources/dijit"
},
{
name: "dojox",
location: "./sources/dojox"
}
],
layers: {
"dojo/dojo": {
name: "myDojo.js",
include: [ "dojo/dojo" ],
boot: true,
dependencies: [ "dojo/parser", "dojo/data/ItemFileReadStore", "dijit/themes/tundra", "dijit/Dialog", "dijit/form/Form", "dijit/form/Button", "dijit/form/CheckBox", "dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/FilteringSelect", "dijit/form/NumberSpinner", "dijit/form/Textarea", "dijit/form/TextBox", "dijit/form/TimeTextBox", "dijit/form/ValidationTextBox", "dijit/layout/ContentPane", "dijit/layout/TabContainer", "dijit/Tooltip", "dojox/widget/ColorPicker" ]
}
},
resourceTags: {
amd: function (filename, mid) {
return /\.js$/.test(filename);
}
}
};
When I run the build a release is created. I found the dojo.js which has the size of about 580 KB uncompressed. But I did not fond my application file and the compressed css file with all styles.
What am I doing wrong?
Thanks, Ralf
Your layer specification seems to be incorrect. Try this instead:
layers: {
"dojo/myDojo": {
include: [ "dojo/parser", "dojo/data/ItemFileReadStore",
"dijit/themes/tundra", "dijit/Dialog", "dijit/form/Form",
"dijit/form/Button", "dijit/form/CheckBox",
"dijit/form/ComboBox", "dijit/form/DateTextBox",
"dijit/form/FilteringSelect", "dijit/form/NumberSpinner",
"dijit/form/Textarea", "dijit/form/TextBox",
"dijit/form/TimeTextBox", "dijit/form/ValidationTextBox",
"dijit/layout/ContentPane", "dijit/layout/TabContainer",
"dijit/Tooltip", "dojox/widget/ColorPicker"
],
boot: true
}
},
References
http://dojotoolkit.org/reference-guide/1.7/build/
http://dojotoolkit.org/documentation/tutorials/1.7/build/