前端:检测 package.json 中声明的依赖在项目中是否被使用/import


概述

前端面试常见问题之一,个人认为也是实际开发中必要的技能。

三种方法

先安装一个axios用作测试,并且暂时不在项目中引入 (import)

npm i axios

安装axios后可以看到package.json中已存在:
在这里插入图片描述

1. npm-check

安装:
这里我是全局安装:

npm install -g npm-check

使用:
控制台输入npm-check,可以看到成功检测出axios未使用:
在这里插入图片描述

2. depcheck

安装和使用同上,只是最后展示有略微区别


安装:

npm install -g depcheck

使用:
控制台输入depcheck,可以看到成功检测出axios未使用:

在这里插入图片描述

3. Eslint

法一:直接在Vscode的插件商店里安装Eslint插件

法二:手动安装**(更复杂,但配置更丰富)

安装:

npm install eslint --save-dev

需要用户选择一些项目开发要求,根据自己需求即可。我是Vue + js,选择如下:
在这里插入图片描述
初始化生成配置文件eslint.config.js(位于根目录)

npx eslint --init

Eslint9.0后其配置文件就变成了eslint.config.js,以前是.eslintrc.js(后缀不一定是.js,取决于初始化时选择的是否是JavaScript)

安装eslint-plugin-unused-imports

npm install eslint-plugin-unused-imports --save-dev

.eslintrc.js配置(Eslint版本低于9.0):

{
  "plugins": [
    "unused-imports"
  ],
  "rules": {
    "unused-imports/no-unused-imports": "error"
  }
}

运行Eslint

npx eslint .

Eslint版本大于9.0:

Eslint9.0之后的插件配置其实我没太玩明白,按官方文档配置了一下,可以正常使用。仅供参考,欢迎勘误:

// eslint.config.js
import globals from "globals";
import pluginJs from "@eslint/js";
import pluginVue from "eslint-plugin-vue";
import unusedImports from 'eslint-plugin-unused-imports';

export default [
  {files: ["**/*.{js,mjs,cjs,vue}"]},
  {languageOptions: { globals: globals.browser }},
  pluginJs.configs.recommended,
  ...pluginVue.configs["flat/essential"],
  {
     plugins: {
      "unused-imports": unusedImports
    },
    rules: {
      "unused-imports/no-unused-imports": "error"
    }
  }
];

运行Eslint

npx eslint .

效果:
这里我引入了ref但未使用。可以看到Eslint的提示,并且由于上面配置的是"unused-imports/no-unused-imports": "error",所以这里是红色波浪线。
在这里插入图片描述

总结

  • 个人认为,前两种工具适用于开发完成后项目整体检查(当然,也可以在控制台切到某一个文件夹目录下单独对这个文件夹内的代码进行检测)
  • Eslint适用于开发过程中的提醒,因为是实时
前端代码实现: 首先,创建一个新的React项目: ``` npx create-react-app todo-app --template typescript ``` 进入项目目录并安装必要的依赖: ``` cd todo-app npm install axios --save npm install @types/axios --save-dev ``` 我们需要使用axios来处理与后端的数据交互。 接下来,创建一个Todo组件,并在其实现Todo应用的逻辑: ```tsx import React, { useState, useEffect } from 'react'; import axios from 'axios'; interface Todo { id: number; title: string; completed: boolean; } const Todo: React.FC = () => { const [todos, setTodos] = useState<Todo[]>([]); const [newTodo, setNewTodo] = useState<string>(''); useEffect(() => { getTodos(); }, []); const getTodos = async () => { const response = await axios.get('http://localhost:3001/todos'); setTodos(response.data); }; const addTodo = async () => { const response = await axios.post('http://localhost:3001/todos', { title: newTodo, completed: false }); setTodos([...todos, response.data]); setNewTodo(''); }; const deleteTodo = async (id: number) => { await axios.delete(`http://localhost:3001/todos/${id}`); const newTodos = todos.filter((todo) => todo.id !== id); setTodos(newTodos); }; const toggleTodo = async (id: number) => { const todo = todos.find((todo) => todo.id === id); await axios.patch(`http://localhost:3001/todos/${id}`, { completed: !todo?.completed }); const newTodos = todos.map((todo) => todo.id === id ? { ...todo, completed: !todo.completed } : todo ); setTodos(newTodos); }; return ( <div> <h1>Todo App</h1> <div> <input type="text" placeholder="Add new todo" value={newTodo} onChange={(e) => setNewTodo(e.target.value)} /> <button onClick={addTodo}>Add</button> </div> <ul> {todos.map((todo) => ( <li key={todo.id}> <input type="checkbox" checked={todo.completed} onChange={() => toggleTodo(todo.id)} /> <span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}> {todo.title} </span> <button onClick={() => deleteTodo(todo.id)}>Delete</button> </li> ))} </ul> </div> ); }; export default Todo; ``` 在这个组件,我们首先定义了一个Todo接口,用于表示Todo数据的结构。然后,我们使用useState来定义了todos和newTodo两个状态变量。 在组件加载完成的时候,我们会调用getTodos函数来获取所有的Todo。 addTodo函数用于添加新的Todo。我们会向后端发送一个POST请求,并将返回的Todo添加到todos数组。 deleteTodo函数用于删除一个Todo。我们会向后端发送一个DELETE请求,并从todos数组过滤掉被删除的Todo。 toggleTodo函数用于切换一个Todo的完成状态。我们会向后端发送一个PATCH请求,并更新todos数组对应的Todo。 最后,在组件的渲染,我们会展示所有的Todo,并提供添加、删除和切换完成状态的功能。 接下来,我们需要将静态资源编译到node.js的静态资源目录。在package.json添加以下代码: ```json "homepage": "/", "scripts": { "start": "react-scripts start", "build": "react-scripts build && cp -r build/* ../backend/public", "test": "react-scripts test", "eject": "react-scripts eject" } ``` 这里,我们使用了cp命令将build目录的文件复制到backend/public目录。这样,我们就可以在后端访问到这些静态资源了。 后端代码实现: 首先,我们需要创建一个新的node.js项目,并安装必要的依赖: ``` npm init -y npm install express cors helmet morgan --save npm install @types/express @types/cors @types/helmet @types/morgan --save-dev ``` 这里,我们使用了express来搭建后端服务器,使用了cors来处理跨域请求,使用了helmet来增强安全性,使用了morgan来记录日志。 接下来,创建一个server.ts文件,并编写以下代码: ```ts import express from 'express'; import cors from 'cors'; import helmet from 'helmet'; import morgan from 'morgan'; import fs from 'fs'; import path from 'path'; const app = express(); const port = 3001; const todosFilePath = path.join(__dirname, 'todos.json'); app.use(express.json()); app.use(cors()); app.use(helmet()); app.use(morgan('tiny')); app.get('/todos', (req, res) => { const todos = JSON.parse(fs.readFileSync(todosFilePath).toString()); res.send(todos); }); app.post('/todos', (req, res) => { const todos = JSON.parse(fs.readFileSync(todosFilePath).toString()); const newTodo = { id: todos.length > 0 ? todos[todos.length - 1].id + 1 : 1, ...req.body }; todos.push(newTodo); fs.writeFileSync(todosFilePath, JSON.stringify(todos)); res.send(newTodo); }); app.delete('/todos/:id', (req, res) => { const todos = JSON.parse(fs.readFileSync(todosFilePath).toString()); const newTodos = todos.filter((todo) => todo.id !== parseInt(req.params.id)); fs.writeFileSync(todosFilePath, JSON.stringify(newTodos)); res.send('Todo deleted'); }); app.patch('/todos/:id', (req, res) => { const todos = JSON.parse(fs.readFileSync(todosFilePath).toString()); const todoIndex = todos.findIndex((todo) => todo.id === parseInt(req.params.id)); todos[todoIndex] = { ...todos[todoIndex], ...req.body }; fs.writeFileSync(todosFilePath, JSON.stringify(todos)); res.send('Todo updated'); }); app.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); }); ``` 在这个文件,我们首先引入了必要的依赖,并创建了一个express应用和一个端口号常量port。 todosFilePath是我们存储Todo数据的文件路径。我们使用fs模块来读写这个文件的数据。 接下来,我们使用了express的间件来增强应用的功能。express.json()用于处理请求体的JSON数据,cors用于处理跨域请求,helmet用于增强安全性,morgan用于记录日志。 我们定义了四个路由: - GET /todos:用于获取所有的Todo。 - POST /todos:用于添加一个新的Todo。 - DELETE /todos/:id:用于删除一个Todo。 - PATCH /todos/:id:用于更新一个Todo的完成状态。 在每个路由的处理函数,我们都会读取todos.json文件的数据,并对其进行相应的操作。然后,我们会将修改后的数据写回到文件,并返回相应的响应。 最后,我们使用app.listen()方法来启动应用,并监听port端口。 在完成了以上代码之后,我们可以使用以下命令来启动应用: ``` npm run build cd ../backend npm start ``` 这样,我们就可以在http://localhost:3000访问到Todo应用了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值