Run type check for all web app packages in CI (#22578)
* Fix incorrect usage of types pacakge * Make platform packages properly expose their type definitions * Have Boards, Channels, and Playbooks get types from platform packages properly * Run type check for all web app packages in CI * Fix incorrect job name
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
2eb5dac9b7
Коммит
1edbde8aa3
5
.github/workflows/channels-ci.yml
поставляемый
5
.github/workflows/channels-ci.yml
поставляемый
@@ -80,7 +80,7 @@ jobs:
|
|||||||
npm run mmjstool -- i18n clean-empty --webapp-dir ./src --mobile-dir /tmp/fake-mobile-dir --check
|
npm run mmjstool -- i18n clean-empty --webapp-dir ./src --mobile-dir /tmp/fake-mobile-dir --check
|
||||||
npm run mmjstool -- i18n check-empty-src --webapp-dir ./src --mobile-dir /tmp/fake-mobile-dir
|
npm run mmjstool -- i18n check-empty-src --webapp-dir ./src --mobile-dir /tmp/fake-mobile-dir
|
||||||
rm -rf tmp
|
rm -rf tmp
|
||||||
check-type:
|
check-types:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -109,12 +109,11 @@ jobs:
|
|||||||
make node_modules
|
make node_modules
|
||||||
# make channels/e2e/playwright/node_modules
|
# make channels/e2e/playwright/node_modules
|
||||||
- name: ci/lint
|
- name: ci/lint
|
||||||
working-directory: webapp/channels
|
|
||||||
run: |
|
run: |
|
||||||
npm run check-types
|
npm run check-types
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
needs: [check-type, check-i18n, check-lint]
|
needs: [check-types, check-i18n, check-lint]
|
||||||
permissions:
|
permissions:
|
||||||
checks: write
|
checks: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|||||||
1
webapp/.gitignore
поставляемый
1
webapp/.gitignore
поставляемый
@@ -2,6 +2,7 @@
|
|||||||
junit.xml
|
junit.xml
|
||||||
node_modules
|
node_modules
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
.rollup.cache
|
||||||
|
|
||||||
channels/dist
|
channels/dist
|
||||||
playbooks/dist
|
playbooks/dist
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"check-style": "stylelint **/*.scss",
|
"check-style": "stylelint **/*.scss",
|
||||||
"check-style:fix": "npm run check-style -- --fix",
|
"check-style:fix": "npm run check-style -- --fix",
|
||||||
"check-style:fix:prettier": "prettier --write './src/**/*.scss'",
|
"check-style:fix:prettier": "prettier --write './src/**/*.scss'",
|
||||||
"check-types": "tsc",
|
"check-types": "tsc -b",
|
||||||
"check-types:fix": "npm run check-types -- --noEmit --fix",
|
"check-types:fix": "npm run check-types -- --noEmit --fix",
|
||||||
"check": "npm run check-lint && npm run check-style",
|
"check": "npm run check-lint && npm run check-style",
|
||||||
"fix": "npm run check-lint:fix && npm run check-style:fix",
|
"fix": "npm run check-lint:fix && npm run check-style:fix",
|
||||||
|
|||||||
@@ -18,25 +18,18 @@
|
|||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"incremental": false,
|
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"typeRoots": [ "./src/types", "./node_modules/@types"],
|
"typeRoots": [ "./src/types", "./node_modules/@types"],
|
||||||
"paths": {
|
"composite": true
|
||||||
"@mattermost/types/*": ["../platform/packages/types/src/*"],
|
|
||||||
"@mattermost/client": ["../platform/client/src"],
|
|
||||||
"@mattermost/components": ["../platform/components/src"],
|
|
||||||
// "mattermost-redux/*": ["../channels/src/packages/mattermost-redux/src/*"],
|
|
||||||
// "reselect": ["../channels/src/packages/reselect/src"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"**/*"
|
"./i18n/*.json",
|
||||||
|
"./src/**/*",
|
||||||
],
|
],
|
||||||
"exclude": [
|
"references": [
|
||||||
".git",
|
{"path": "../platform/client"},
|
||||||
"!node_modules/@types",
|
{"path": "../platform/types"}
|
||||||
"dist",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';
|
import {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';
|
||||||
|
|
||||||
import {GlobalState} from '@mattermost/types/store.js';
|
import {GlobalState} from '@mattermost/types/store';
|
||||||
import {ActionFunc, ActionResult, GenericAction} from 'mattermost-redux/types/actions.js';
|
import {ActionFunc, ActionResult, GenericAction} from 'mattermost-redux/types/actions.js';
|
||||||
import {Role} from '@mattermost/types/roles.js';
|
import {Role} from '@mattermost/types/roles';
|
||||||
|
|
||||||
import {loadRolesIfNeeded, editRole} from 'mattermost-redux/actions/roles';
|
import {loadRolesIfNeeded, editRole} from 'mattermost-redux/actions/roles';
|
||||||
import {getRoles} from 'mattermost-redux/selectors/entities/roles';
|
import {getRoles} from 'mattermost-redux/selectors/entities/roles';
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';
|
|||||||
|
|
||||||
import {GlobalState} from 'types/store/index.js';
|
import {GlobalState} from 'types/store/index.js';
|
||||||
|
|
||||||
import {Post} from '@mattermost/types/posts.js';
|
import {Post} from '@mattermost/types/posts';
|
||||||
|
|
||||||
import {FileInfo} from '@mattermost/types/files.js';
|
import {FileInfo} from '@mattermost/types/files';
|
||||||
|
|
||||||
import {ActionResult, GetStateFunc, DispatchFunc} from 'mattermost-redux/types/actions.js';
|
import {ActionResult, GetStateFunc, DispatchFunc} from 'mattermost-redux/types/actions.js';
|
||||||
|
|
||||||
import {CommandArgs} from '@mattermost/types/integrations.js';
|
import {CommandArgs} from '@mattermost/types/integrations';
|
||||||
|
|
||||||
import {ModalData} from 'types/actions.js';
|
import {ModalData} from 'types/actions.js';
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import React, {ComponentType, useRef} from 'react';
|
|||||||
import {match, Route, Switch} from 'react-router-dom';
|
import {match, Route, Switch} from 'react-router-dom';
|
||||||
import {createGlobalStyle} from 'styled-components';
|
import {createGlobalStyle} from 'styled-components';
|
||||||
|
|
||||||
import {UserProfile} from '@mattermost/types/users.js';
|
import {UserProfile} from '@mattermost/types/users';
|
||||||
|
|
||||||
import {Team} from '@mattermost/types/teams.js';
|
import {Team} from '@mattermost/types/teams';
|
||||||
|
|
||||||
import Bots from 'components/integrations/bots';
|
import Bots from 'components/integrations/bots';
|
||||||
import AddBot from 'components/integrations/bots/add_bot';
|
import AddBot from 'components/integrations/bots/add_bot';
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import {useHistory} from 'react-router-dom';
|
import {useHistory} from 'react-router-dom';
|
||||||
|
|
||||||
import {Command} from '@mattermost/types/integrations.js';
|
import {Command} from '@mattermost/types/integrations';
|
||||||
import {Team} from '@mattermost/types/teams.js';
|
import {Team} from '@mattermost/types/teams';
|
||||||
|
|
||||||
import {ActionResult} from 'mattermost-redux/types/actions.js';
|
import {ActionResult} from 'mattermost-redux/types/actions.js';
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import {useHistory} from 'react-router-dom';
|
import {useHistory} from 'react-router-dom';
|
||||||
|
|
||||||
import {OAuthApp} from '@mattermost/types/integrations.js';
|
import {OAuthApp} from '@mattermost/types/integrations';
|
||||||
import {Team} from '@mattermost/types/teams.js';
|
import {Team} from '@mattermost/types/teams';
|
||||||
|
|
||||||
import {ActionResult} from 'mattermost-redux/types/actions.js';
|
import {ActionResult} from 'mattermost-redux/types/actions.js';
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
import {Team} from '@mattermost/types/teams.js';
|
import {Team} from '@mattermost/types/teams';
|
||||||
|
|
||||||
import {Permissions} from 'mattermost-redux/constants';
|
import {Permissions} from 'mattermost-redux/constants';
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import {GlobalState} from 'types/store/index.js';
|
|||||||
|
|
||||||
import {ActionFunc, GenericAction} from 'mattermost-redux/types/actions.js';
|
import {ActionFunc, GenericAction} from 'mattermost-redux/types/actions.js';
|
||||||
|
|
||||||
import {UserStatus} from '@mattermost/types/users.js';
|
import {UserStatus} from '@mattermost/types/users';
|
||||||
|
|
||||||
import {PreferenceType} from '@mattermost/types/preferences.js';
|
import {PreferenceType} from '@mattermost/types/preferences';
|
||||||
|
|
||||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||||
import {setStatus} from 'mattermost-redux/actions/users';
|
import {setStatus} from 'mattermost-redux/actions/users';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import {Channel} from '@mattermost/types/channels.js';
|
import {Channel} from '@mattermost/types/channels';
|
||||||
import {ActionResult} from 'mattermost-redux/types/actions.js';
|
import {ActionResult} from 'mattermost-redux/types/actions.js';
|
||||||
|
|
||||||
import {getMyChannels, getMyChannelMemberships} from 'mattermost-redux/selectors/entities/channels';
|
import {getMyChannels, getMyChannelMemberships} from 'mattermost-redux/selectors/entities/channels';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {ServerError} from '@mattermost/types/errors.js';
|
import {ServerError} from '@mattermost/types/errors';
|
||||||
import {ActionFunc} from 'mattermost-redux/types/actions.js';
|
import {ActionFunc} from 'mattermost-redux/types/actions.js';
|
||||||
|
|
||||||
import {isDirectChannel, isGroupChannel, sortChannelsByTypeListAndDisplayName} from 'mattermost-redux/utils/channel_utils';
|
import {isDirectChannel, isGroupChannel, sortChannelsByTypeListAndDisplayName} from 'mattermost-redux/utils/channel_utils';
|
||||||
|
|||||||
@@ -22,10 +22,8 @@
|
|||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"baseUrl": "./src",
|
"baseUrl": "./src",
|
||||||
"useUnknownInCatchVariables": false,
|
"useUnknownInCatchVariables": false,
|
||||||
|
"composite": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@mattermost/client": ["../../platform/client/src"],
|
|
||||||
"@mattermost/components": ["../../platform/components/src"],
|
|
||||||
"@mattermost/types/*": ["../../platform/types/src/*"],
|
|
||||||
"mattermost-redux/*": ["packages/mattermost-redux/src/*"],
|
"mattermost-redux/*": ["packages/mattermost-redux/src/*"],
|
||||||
"reselect": ["packages/reselect/src"],
|
"reselect": ["packages/reselect/src"],
|
||||||
"@mui/styled-engine": ["./node_modules/@mui/styled-engine-sc"],
|
"@mui/styled-engine": ["./node_modules/@mui/styled-engine-sc"],
|
||||||
@@ -35,17 +33,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src/**/*"
|
"./src/**/*",
|
||||||
],
|
"./src/**/*.json"
|
||||||
"exclude": [
|
|
||||||
"dist",
|
|
||||||
"e2e/cypress",
|
|
||||||
"e2e/playwright",
|
|
||||||
"!node_modules/@types",
|
|
||||||
"coverage"
|
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{"path": "../platform/client"},
|
{"path": "../platform/client"},
|
||||||
|
{"path": "../platform/components"},
|
||||||
{"path": "../platform/types"}
|
{"path": "../platform/types"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
],
|
],
|
||||||
"main": "./lib/index.js",
|
"main": "lib/index.js",
|
||||||
|
"types": "lib/index.d.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "github:mattermost/mattermost-webapp",
|
"url": "github:mattermost/mattermost-webapp",
|
||||||
|
|||||||
@@ -12,12 +12,14 @@
|
|||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"composite": true,
|
"composite": true
|
||||||
"paths": {
|
|
||||||
"@mattermost/types/*": ["../types/lib/*"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"exclude": ["**/node_modules", "**/lib", "**/*.test.js", "**/*.test.ts"],
|
"include": [
|
||||||
|
"./src/**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/*.test.*"
|
||||||
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{"path": "../types"}
|
{"path": "../types"}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@mattermost/components",
|
"name": "@mattermost/components",
|
||||||
"version": "7.4.0",
|
"version": "7.4.0",
|
||||||
"module": "dist/index.esm.js",
|
"module": "dist/index.esm.js",
|
||||||
"types": "dist/index.esm.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"styles": "dist/index.esm.css",
|
"styles": "dist/index.esm.css",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup -c",
|
"build": "rollup -c",
|
||||||
|
|||||||
@@ -10,12 +10,9 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"paths": {
|
"rootDir": "src",
|
||||||
"mattermost-redux/*": ["./node_modules/mattermost-redux/src/*"],
|
"composite": true
|
||||||
"@mattermost/types/*": ["./node_modules/@mattermost/types/src/*"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,21 +12,6 @@ import {UserProfile} from '@mattermost/types/users';
|
|||||||
|
|
||||||
For technologies that don't support that yet, you can add an alias in its package resolution settings to support that.
|
For technologies that don't support that yet, you can add an alias in its package resolution settings to support that.
|
||||||
|
|
||||||
### TypeScript
|
|
||||||
|
|
||||||
In the `tsconfig.json`, you can use `compilerOptions.paths` to add that alias. This also requires a `compilerOptions.baseUrl` if you haven't set that already.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@mattermost/types/*": ["node_modules/@mattermost/types/lib/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Jest
|
### Jest
|
||||||
|
|
||||||
In your Jest config, you can use the `moduleNameMapper` field to add that alias.
|
In your Jest config, you can use the `moduleNameMapper` field to add that alias.
|
||||||
|
|||||||
@@ -13,7 +13,11 @@
|
|||||||
"exports": {
|
"exports": {
|
||||||
"./*": "./lib/*.js"
|
"./*": "./lib/*.js"
|
||||||
},
|
},
|
||||||
"types": "./lib/*.d.ts",
|
"typesVersions": {
|
||||||
|
">=3.1": {
|
||||||
|
"*": ["./lib/*.d.ts"]
|
||||||
|
}
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "github:mattermost/mattermost-webapp",
|
"url": "github:mattermost/mattermost-webapp",
|
||||||
|
|||||||
@@ -14,5 +14,10 @@
|
|||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"composite": true
|
"composite": true
|
||||||
},
|
},
|
||||||
"exclude": ["**/node_modules", "**/lib", "**/*.test.js", "**/*.test.ts"]
|
"include": [
|
||||||
|
"./src/**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/*.test.*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
"test": "jest --forceExit --detectOpenHandles --verbose",
|
"test": "jest --forceExit --detectOpenHandles --verbose",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"test-ci": "jest --forceExit --detectOpenHandles --maxWorkers=2",
|
"test-ci": "jest --forceExit --detectOpenHandles --maxWorkers=2",
|
||||||
"check-types": "tsc",
|
"check-types": "tsc -b",
|
||||||
"extract": "formatjs extract 'src/**/*.{ts,tsx}' --out-file i18n/temp.json --id-interpolation-pattern '[sha512:contenthash:base64:6]' && formatjs compile 'i18n/temp.json' --out-file i18n/en.json && rm i18n/temp.json",
|
"extract": "formatjs extract 'src/**/*.{ts,tsx}' --out-file i18n/temp.json --id-interpolation-pattern '[sha512:contenthash:base64:6]' && formatjs compile 'i18n/temp.json' --out-file i18n/en.json && rm i18n/temp.json",
|
||||||
"graphql": "graphql-codegen --config graphql_gen.ts",
|
"graphql": "graphql-codegen --config graphql_gen.ts",
|
||||||
"report-unused-exports": "ts-prune",
|
"report-unused-exports": "ts-prune",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {Modal} from 'react-bootstrap';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import {useDispatch, useSelector} from 'react-redux';
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
import {searchProfiles} from 'mattermost-redux/actions/users';
|
import {searchProfiles} from 'mattermost-redux/actions/users';
|
||||||
import {UserProfile} from 'mattermost-webapp/packages/types/src/users';
|
import {UserProfile} from '@mattermost/types/users';
|
||||||
import {LightningBoltOutlineIcon} from '@mattermost/compass-icons/components';
|
import {LightningBoltOutlineIcon} from '@mattermost/compass-icons/components';
|
||||||
import {OptionTypeBase, StylesConfig} from 'react-select';
|
import {OptionTypeBase, StylesConfig} from 'react-select';
|
||||||
import {General} from 'mattermost-redux/constants';
|
import {General} from 'mattermost-redux/constants';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import styled from 'styled-components';
|
|||||||
import {AccountPlusOutlineIcon} from '@mattermost/compass-icons/components';
|
import {AccountPlusOutlineIcon} from '@mattermost/compass-icons/components';
|
||||||
import {useDispatch, useSelector} from 'react-redux';
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
import {getProfilesByIds} from 'mattermost-redux/actions/users';
|
import {getProfilesByIds} from 'mattermost-redux/actions/users';
|
||||||
import {UserProfile} from 'mattermost-webapp/packages/types/src/users';
|
import {UserProfile} from '@mattermost/types/users';
|
||||||
import {sortByUsername} from 'mattermost-redux/utils/user_utils';
|
import {sortByUsername} from 'mattermost-redux/utils/user_utils';
|
||||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
|
|||||||
@@ -24,15 +24,13 @@
|
|||||||
"useUnknownInCatchVariables": false,
|
"useUnknownInCatchVariables": false,
|
||||||
"paths": {
|
"paths": {
|
||||||
"src": ["src"],
|
"src": ["src"],
|
||||||
"@mattermost/types/*": ["../platform/packages/types/src/*"],
|
|
||||||
"@mattermost/client": ["../platform/client/src"],
|
|
||||||
"@mattermost/components": ["../platform/components/src"],
|
|
||||||
"mattermost-redux/*": ["../channels/src/packages/mattermost-redux/src/*"],
|
"mattermost-redux/*": ["../channels/src/packages/mattermost-redux/src/*"],
|
||||||
"reselect": ["../channels/src/packages/reselect/src"]
|
"reselect": ["../channels/src/packages/reselect/src"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./**/*"
|
"./i18n/*.json",
|
||||||
|
"./src/**/*",
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"dist",
|
"dist",
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user