1.创建项目
npx create-react-app my-app
2.将webpack配置提取出来
npm eject
3.删除src文件下除了index.js app.js 的所有文件
4.配置less,
1.安装less
npm i less less-loader --save-dev
2.在webpack.config文件里面添加
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
// 添加下面两行
const lessRegex = /\.(less)$/;
const lessModuleRegex = /\.module\.less$/;
3.接着配置loader,同样我们找到sass相关的写法,在后面添加:
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
// 添加 less 相关配置
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
// getLocalIdent: getCSSModuleLocalIdent,
localIdentName: '[local]_[hash:base64:5]'
},
},
'less-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See <https://github.com/webpack/webpack/issues/6571>
sideEffects: true,
},
// Adds support for CSS Modules, but using LESS
// using the extension .module.less or .module.less
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
// getLocalIdent: getCSSModuleLocalIdent,
localIdentName: '[local]_[hash:base64:5]'
},
},
'less-loader'
),
},
...
5.在src下添加global.less,并引入app.js
/* stylelint-disable selector-pseudo-element-colon-notation */
/* stylelint-disable rule-empty-line-before */
h1,
h2,
h6,
p,
th,
td {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
img {
border: 0;
}
li {
list-style: none;
}
html {
height: 100%;
}
body {
background: #f0f2f5;
margin:0
}
#root {
height: 100%;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
.ant-modal-title {
font-weight: 550;
}
.ant-table-cell {
a {
margin-right: 10px;
color: #06c;
}
}
.ant-picker {
width: 224px;
margin: 0 10px 10px;
}
.ant-layout-content {
position: relative;
}
.container {
padding: 20px 10px;
background-color: #fff;
.formWrap {
display: flex;
justify-content: space-between;
}
.formWrapLeft {
display: flex;
flex-wrap: wrap;
padding: 0 10px 10px;
text-align: center;
.dateText {
margin-top: 4px;
color: #666;
font-size: 14px;
}
.select {
width: 130px;
margin: 0 20px 10px 10px;
}
}
}
.ant-menu-inline .ant-menu-item-selected::after {
display: none;
}
.ant-select-selector {
text-align: left;
}
.ant-rate {
color: #ff8b30;
font-size: 16px;
}
.ant-table {
color: #fff;
background: none;
}
.ant-table-thead > tr > th {
padding: 10px 0px 10px 10px;
color: #fff;
background: none;
border: none;
}
.ant-table-tbody > tr > td {
padding: 10px 0px 10px 10px;
border-bottom: 1px solid rgb(41, 127, 203, 0.5);
}
.ant-table-tbody > tr.ant-table-row:hover > td {
background: rgba(27, 87, 144, 0.3);
border-top: 1px solid #297fcb;
border-bottom: 1px solid #297fcb;
}
.ant-select-dropdown {
background: rgba(109, 185, 249, 0.2);
}
.ant-select-item-option-selected:not(.ant-select-item-option-disabled) {
color: #fff;
background: rgba(109, 185, 249, 0.6);
}
.ant-select-item {
color: #fff;
}
.ant-select-item-option-active:not(.ant-select-item-option-disabled) {
background: rgba(109, 185, 249, 0.6);
}
.amap-logo {
display: none !important;
}
6.配置代理
npm i axios
在pages/utils下创建reauest.js
// import { history } from 'umi';
// import { message } from 'antd';
const api = axios.create({
baseURL: '/api',
// baseURL: '/mock/api',
// withCredentials: true,
// timeout: 500
});
// 请求拦截
api.interceptors.request.use(
(config) => {
let token = localStorage.getItem('sid');
if (!config.login && token) {
config.headers['token'] = token; // 设置请求头
}
if (config.download) {
// download设置responseType
config.responseType = 'blob';
}
console.log(api,'api')
if (config.upload) {
config.headers['Content-Type'] = 'multipart/form-data';
}
return config;
},
(error) => {
return Promise.reject(error);
},
);
// 返回拦截
api.interceptors.response.use(
(response) => {
if (response.status === 200) {
if (response.config.download) {
// download
let objectUrl = URL.createObjectURL(new Blob([response.data])); // 转换文件下载路径
let fileName = decodeURI(response.headers['content-disposition'].split('=')[1]); // 获取文件名
const link = document.createElement('a');
link.download = fileName;
link.href = objectUrl;
link.click();
return Promise.resolve(response);
}
return Promise.resolve(response.data);
} else {
return Promise.reject(response);
}
},
(error) => {
if (error.response.status === 401) {
localStorage.removeItem('sid');
localStorage.removeItem('userName');
// history.push('/?overtime=true');
}
return Promise.reject(error.response);
},
);
export default api;
在webpackDevServer.config下修改proxy为后并重启项目
// '/api/test': {
// target: 'http://2.0.0.1:3090/',
// changeOrigin: true,
// pathRewrite: {
// '^/api/test': ''
// }
// },
'/api': {
target: 'http://127.0.0.1:3000/',
changeOrigin: true,
pathRewrite: { '^/api': '/' },
},
},
7.配置绝对路径
alias: {
'@@': path.resolve(__dirname, '../src'),
},
},
8.配置路由
1.在src下创建routers文件夹
import { Outlet, useRoutes } from 'react-router-dom';
const Index = lazy(() => import('@/views/Index/index'));
const Information = lazy(() => import('@/views/Information/index'));
const Contacts = lazy(() => import('@/views/Contacts/index'));
const routes = [
{
path: '/index',
element: <Suspense fallback={<div>稍等</div>}><Index /></Suspense> ,
},
{
path: '/personal',
element: <Outlet/>,
children: [
{
path: 'information',
// element: <Information />
element: <Suspense fallback={<div>稍等</div>}><Information /></Suspense> ,
},
{
path: 'contacts',
// element: <Contacts />
element: <Suspense fallback={<div>稍等</div>}><Contacts /></Suspense> ,
}
]
}
];
const WrappedRoutes = () => {
return useRoutes(routes);
};
export default WrappedRoutes;
2.并在index.js导入
import { BrowserRouter } from "react-router-dom";并在return里面放在最外层
9.国际化配置
import zhCN from 'antd/lib/locale/zh_CN'
// 并在return里面包裹app组件
<ConfigProvider locale={zhCN}>
<App />
</ConfigProvider>
10.配置导航栏
1.创建components文件 siders文件
import WrappedRoutes from '@@/routers/index';
import { Layout, Menu } from 'antd';
import { useLocation, useNavigate } from 'react-router-dom';
import {
PieChartOutlined,
PushpinOutlined,
IdcardOutlined,
ContactsOutlined
} from '@ant-design/icons';
const { Header, Content, Footer, Sider } = Layout;
const menuList = [{
label: "首页",
key: "/index",
icon: <PieChartOutlined rev={undefined} />,
},
{
label: "个人办公",
key: "/personal",
icon: <PushpinOutlined rev={undefined} />,
children: [
{
label: "个人信息",
icon: <IdcardOutlined rev={undefined} />,
key: "/personal/information"
},
{
label: "通讯录",
icon: <ContactsOutlined rev={undefined} />,
key: "/personal/contacts"
}
]
}]
const App = () => {
const navigate = useNavigate();
const { pathname } = useLocation(); // 获取当前url
const handleClick = (e) => {
navigate(e.key); // 实现跳转
}
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider>
<div style={{ height: 90 }} />
<Menu
theme="dark"
mode="inline"
selectedKeys={[pathname]}
items={menuList} onClick={handleClick}
/>
</Sider>
<Layout>
<Content style={{ margin: 16 }}>
<WrappedRoutes />
</Content>
</Layout>
</Layout>
)
};
export default App;
2.将文件导入app,js
import { Layout } from 'antd';
import Siders from '@@/components/sider'
const App = () => {
return (
<Layout style={{ minHeight: '100vh' }}>
<Siders></Siders>
</Layout>
)
};
export default App;
11.全局mobx
1.在src下新建store文件夹,存放状态,store下的index.js统一管理所有状态
import cart from '@@/store/cart'
import counter from '@@/store/counter'
// store/Counter.ts
class RootStore {
cart = cart
counter = counter
}
const store = new RootStore()
// 创建一个上下文对象,用于跨级组件通讯
// 如果 createContext 提供了默认值,不需要 Provider
const Context = createContext(store)
export default store;
2.子状态文件
import { action, makeObservable, observable } from 'mobx'
import api from '@@/utils/request.js'
class Counter {
count = 0
data = []
constructor() {
// 参数1:target,把谁变成响应式(可观察)
// 参数2:指定哪些属性或者方法变成可观察
makeObservable(this, {
count: observable,
data: observable,
increment: action.bound,
decrement: action.bound,
reset: action.bound,
apiFn: action.bound,
})
}
increment() {
this.count++
}
decrement() {
this.count--
}
reset() {
this.count = 0
}
async apiFn() {
await api.get('/daxia/daxia').then(value => {
this.data = value.value
})
}
}
const counter = new Counter()
export default counter
3.视图文件
import { observer,inject } from 'mobx-react'
import { useEffect} from 'react'
import { Space, Table, Tag } from 'antd';
const Text = ({store}) => {
const {counter} = store
useEffect(() => {
counter.apiFn()
},[])
const columns = [
{
title: 'bspPath',
dataIndex: 'bspPath',
key: 'bspPath',
render: (text) => <a>{text}</a>,
},
{
title: 'bspName',
dataIndex: 'bspName',
key: 'bspName',
},
{
title: 'objName',
dataIndex: 'objName',
key: 'objName',
},
];
return (
<div>
<h3>计数器案例</h3>
<div>点击次数:{counter.count}</div>
<button onClick={counter.increment}>加1</button>
<button onClick={counter.decrement}> 减1</button >
<button onClick={counter.reset}>重置</button>
<Table columns={columns} dataSource={counter.data} />
</div >
)
}
export default inject('store')(observer(Text));
4.index.js文件传入store
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from "react-router-dom";
import { ConfigProvider } from 'antd'
import zhCN from 'antd/lib/locale/zh_CN'
import { Provider } from 'mobx-react'
import store from '@@/store'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ConfigProvider locale={zhCN}>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</ConfigProvider>
);
12.增加services层
1.创建services文件夹,引入request,导出api接口,让视图层更加专注渲染页面,状态层分离
export async function deleteFun(options) {
try {
let response = await requset.delete('', {
params: options,
});
return response;
} catch (error) {
return error;
}
}
export async function postFun(options) {
try {
let response = await requset.post('', options);
return response;
} catch (error) {
return error;
}
}
export async function getFun(options) {
try {
let response = await requset.get('/daxia/daxia', {
params: options,
});
console.log('response')
return response;
} catch (error) {
return error;
}
}
export async function putFun(options) {
try {
let response = await requset.put('', options);
return response;
} catch (error) {
return error;
}
}
2.修改store里面
...
async apiFn(options = {}) {
await getFun(options).then(value => {
this.data = value.value
})
console.log(this,'this')
}
...
3.修改视图层增加传参
counter.apiFn({参数})
13.增加登陆页面
1.在view下面新增login文件夹
import { Card, Col, Row, Button, message, Form, Input } from 'antd'
import logo from '@@/assets/icon.png'
//useNavigate必须在函数组件中使用,函数组件未大写也报错了
import { useNavigate } from 'react-router-dom'
const Login = () => {
const navigate = useNavigate()
const onFinish = (values) => {
console.log('Success:', values);
message.success('登陆成功')
navigate('/index')
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
return (
<Row>
<Col
md={{
span: 8,
push: 8
}}
xs={{
span: 22,
push: 1
}}
>
<img src={logo}
style={{
display: 'block',
margin: '20px auto',
borderRadius: '16px',
width: '200px'
}}></img>
<Card title='练习管理平台'>
<Form
name="basic"
style={{
maxWidth: 600,
}}
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
label="用户名"
name="username"
rules={[
{
required: true,
message: '请输入用户名!',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="密码"
name="password"
rules={[
{
required: true,
message: '请输入密码!',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item
wrapperCol={{
offset: 8,
span: 16,
}}
>
<Button type="primary" htmlType="submit">
登录
</Button>
</Form.Item>
</Form>
</Card>
</Col>
</Row>
)
}
export default Login
2.修改index.js文件,增加登陆页面路由
import { lazy, Suspense } from "react";
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { ConfigProvider } from 'antd'
import zhCN from 'antd/lib/locale/zh_CN'
import { Provider } from 'mobx-react'
import store from '@@/store'
const Login = lazy(() => import('@@/views/Login/index'));
const App = lazy(() => import('@@/App'));
const Loading = lazy(() => import('@@/views/loading/index'));
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ConfigProvider locale={zhCN}>
<Provider store={store}>
<BrowserRouter>
<Routes>
<Route path='/' element={<Suspense fallback={<Loading />}><Login /></Suspense>}></Route>
<Route path='/*' element={<Suspense fallback={<Loading />}><App /></Suspense>}></Route>
</Routes>
</BrowserRouter>
</Provider>
</ConfigProvider>
);
14.增加退出登录功能,面包屑,页面刷新放丢失
import WrappedRoutes from '@@/routers/index';
import { Layout, Menu, Button, theme, Dropdown, message,Breadcrumb } from 'antd';
import { useLocation, useNavigate } from 'react-router-dom';
import {
PieChartOutlined,
PushpinOutlined,
IdcardOutlined,
ContactsOutlined,
MenuUnfoldOutlined,
MenuFoldOutlined
} from '@ant-design/icons';
import { useState, useEffect } from 'react'
import logo from '@@/assets/icon.png'
import styles from './index.less'
const { Content, Sider, Header } = Layout;
const menuList = [
{
label: "总览",
title: "总览",
key: "/index",
icon: <PieChartOutlined rev={undefined} />,
},
{
label: "个人办公",
title: "个人办公",
key: "/personal",
icon: <PushpinOutlined rev={undefined} />,
children: [
{
label: "个人信息",
title: "个人信息",
icon: <IdcardOutlined rev={undefined} />,
key: "/personal/information"
},
{
label: "通讯录",
title: "通讯录",
icon: <ContactsOutlined rev={undefined} />,
key: "/personal/contacts"
}
]
}]
/**
* 处理刷新页面后menu返回第一个问题
* @param {*} key
* @returns
*/
const findOpenKeys = (key) => {
// console.log(key, 'pathname')
const result = []
const findInfo = arr => {
arr.forEach((item) => {
if (key.includes(item.key)) {
result.push(item.key)
if (item.children) {
findInfo(item.children)
}
}
})
}
findInfo(menuList)
return result
}
/**
* 获取当前选中的所有父节点
* @param {*} key
* @returns
*/
const findDeepPath = key => {
const result = []
const findInfo = arr => {
arr.forEach(item => {
const { children, ...info } = item
result.push(info)
if (children) {
findInfo(children)
}
})
}
//数组扁平化
findInfo(menuList)
const tepData = result.filter(item => key.includes(item.key))
if (tepData.length > 0) {
//这里添加的key值不能和上面的重复,会报错
return [{ title: '首页', key: '/admin/dashboard-admin' }, ...tepData]
}
// return []
}
const App = ({ children }) => {
const [collapsed, setCollapsed] = useState(false);
const navigate = useNavigate();
const { pathname } = useLocation(); // 获取当前url
const [breadcrumbs, setBreadcrumbs] = useState([])
const {
token: { colorBgContainer },
} = theme.useToken();
const handleClick = (e) => {
navigate(e.key); // 实现跳转
}
useEffect(() => {
setBreadcrumbs(findDeepPath(pathname))
}, [pathname])
const temOpenKeys = findOpenKeys(pathname)
const items = [
{ label: '个人中心', key: 'userCenter' },
{ label: '退出', key: 'logout' }
]
const onClick = (value) => {
if (value.key === 'logout') {
navigate('/')
} else {
message.info('暂未开通')
}
console.log('点击事件', value)
}
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider trigger={null} collapsible collapsed={collapsed}>
<div style={{ height: 90 }} />
<Menu
theme="dark"
mode="inline"
defaultOpenKeys={temOpenKeys}
defaultSelectedKeys={temOpenKeys}
selectedKeys={[pathname]}
items={menuList}
onClick={handleClick}
/>
</Sider>
<Layout>
<Header
style={{
padding: 0,
background: colorBgContainer,
}}
>
<Button
type="text"
icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
onClick={() => setCollapsed(!collapsed)}
style={{
fontSize: '16px',
width: 64,
height: 64,
}}
/>
<Dropdown
menu={{
items,
onClick
}}
placement="bottom"
>
<img src={logo} className={styles.logoOut}></img>
</Dropdown>
</Header>
<Content style={{ margin: 16 }}>
<Breadcrumb
items={breadcrumbs}
>
</Breadcrumb>
<WrappedRoutes />
</Content>
</Layout>
</Layout>
)
};
export default App;
15.全局高度撑满问题,需要在antd的Layout组件添加style={{ minHeight: '100vh' }}
16.关闭eslint配置
在webpack.config里面添加
// 关闭eslint
const disableESLintPlugin = true;
17.webpack增加编译进度条展示
//编译进度条
const WebpackBar = require('webpackbar')
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
// makes for a smoother build process.
//增加plugin
new webpack.ProgressPlugin(),//自带的
new WebpackBar()
18.webpack优化,分析包内容,显示打包体积大小
//1.分析包内容,显示打包的文件大小
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
//2.增加plugins
//显示页面打包文件大小
new BundleAnalyzerPlugin({
analyzerMode: 'disabled', // 不启动展示打包报告的http服务器
generateStatsFile: false, // 是否生成stats.json文件
}), // 使用默认配置
// 默认配置的具体配置项
// new BundleAnalyzerPlugin({
// analyzerMode:'server', // 可以是 server、static、json、disabled。在server模式下,分析器将启动HTTP服务器来显示软件包报告。在“静态”模式下,会生成带有报告的单个HTML文件。在disabled模式下,你可以使用这个插件来将generateStatsFile设置为true来生成Webpack Stats JSON文件。
// analyzerHost: '127.0.0.1', // 将在“服务器”模式下使用的端口启动HTTP服务器
// analyzerPort: 8888, // 端口号
// reportFilename: 'report.html', // 路径捆绑,将在static模式下生成的报告文件。相对于捆绑输出目录
// defaultSizes: 'parsed', // 默认显示在报告中的模块大小匹配方式。应该是stat,parsed或者gzip中的一个
// openAnalyzer: false, // 在默认浏览器中是否自动打开报告,默认 true
// generateStatsFile: false, // 如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成
// statsFilename: 'stats.json', // 相对于捆绑输出目录
// statsOptions: null, //stats.toJson()方法的选项。例如,您可以使用source:false选项排除统计文件中模块的来源。在这里查看更多选项:https://github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
// logLevel: 'info', // 日志级别,可以是info, warn, error, silent
// excludeAssets:null, // 用于排除分析一些文件
// }),
//3.在pacgage.json添加
"generateAnalyzFile": "webpack --profile --json > stats.json",
"analyz": "webpack-bundle-analyzer --port 8888 ./stats.json"
//4.先执行npm run generateAnalyzFile
//5.在执行npm run analyz
19.webpack费时优化,显示打包时间
//$ npm i mini-css-extract-plugin@1.3.6 -D 需要回退版本
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin()
// smp.wrap(
//解决显示打包时间和css文件提取冲突问题
const wrapConfig = process.env.NODE_ENV !== 'development' ? smp.wrap : (config) => config;
module.exports = wrapConfig((webpackEnv)=> {webpack配置})
20.webpack报警告,无法映射源文件
在最外层添加文件.env
GENERATE_SOURCEMAP=false
21.增加eslint效验
1.增加.eslintrc.js文件
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": 'module',
"parser":"babel-eslint",
},
"plugins": [
"react"
],
"rules": {
"no-console": 1,
"semi":2
}
}
2.增加.eslintignore文件
/node_moduls
/config
.eslintrc.js
/scripts
3.修改webpack.config.js配置
!disableESLintPlugin &&
new ESLintPlugin({
// Plugin options
context: path.resolve(__dirname,'../src'), //指定文件根目录,类型为字符串
}),
4.删除package.json的eslintConfig配置
5.eslint关闭效验
/* eslint-disable */some code
some code
/* eslint-enable */
2.关闭当前行效验
some code // eslint-disable-line
3.关闭下一行效验
// eslint-disable-next-line
some code
4.关闭整个行效验
/* eslint-disable */
22.配置stylelint
作用:css的书写顺序很重要,会影响浏览器的渲染。正确的书写可以减少浏览器的回流,提升浏览器的dom渲染。
1.安装依赖
npm i stylelint stylelint-config-standard stylelint-order -D
2.增加.stylelintrc.js
extends: ['stylelint-config-standard'],
plugins: ['stylelint-order'],
rules: {
'no-descending-specificity': null,
'function-url-quotes': 'always',
'string-quotes': 'double',
indentation: 4,
'unit-case': null,
'color-hex-case': 'lower',
'color-hex-length': 'long',
'rule-empty-line-before': 'never',
'font-family-no-missing-generic-family-keyword': null,
'block-opening-brace-space-before': 'always',
'property-no-unknown': null,
'no-empty-source': null,
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['deep'],
},
],
'order/properties-order': [
'position',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'justify-content',
'align-items',
'float',
'clear',
'overflow',
'overflow-x',
'overflow-y',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'width',
'min-width',
'max-width',
'height',
'min-height',
'max-height',
'font-size',
'font-family',
'font-weight',
'border',
'border-style',
'border-width',
'border-color',
'border-top',
'border-top-style',
'border-top-width',
'border-top-color',
'border-right',
'border-right-style',
'border-right-width',
'border-right-color',
'border-bottom',
'border-bottom-style',
'border-bottom-width',
'border-bottom-color',
'border-left',
'border-left-style',
'border-left-width',
'border-left-color',
'border-radius',
'text-align',
'text-justify',
'text-indent',
'text-overflow',
'text-decoration',
'white-space',
'color',
'background',
'background-position',
'background-repeat',
'background-size',
'background-color',
'background-clip',
'opacity',
'filter',
'list-style',
'outline',
'visibility',
'box-shadow',
'text-shadow',
'resize',
'transition',
],
},
}
3.下载vscode插件stylelint
"source.fixAll.eslint": true,
//增加如下代码
"source.fixAll.stylelint": true,
},
4.在parkage.json的scripts里面增加
"style": "stylelint 'src/**/*.(css|less)' --fix"
5.忽略检查写法
/* stylelint-disable */
div{
width:100px;
}
2.忽略多行
/* stylelint-disable */
div {
color: red;
}
/* stylelint-enable */
3.忽略一行, 在样式前加入 /* stylelint-disable-next-line */ 以忽略该行
#id {
/* stylelint-disable-next-line */
color: pink !important;
}
4.在 .stylelintrc.json 內设定需要忽略的文件
{
ignoreFiles: ["dist/**/*", "src/assets/scss/abc.scss"]
}