qiankun + Vite + React + Vue + Angular 快速构建前端微服务

news2024/11/23 8:06:40

文章目录

  • 一、主应用 vite
  • 二、微应用 react
  • 三、微应用 vue
  • 四、微应用 angular
  • 五、项目地址


一、主应用 vite

npm

 npm create vite@latest

yarn

 yarn create vite

选择是否继续

Need to install the following packages:
  create-vite@3.2.1
Ok to proceed? (y) y

项目名称

Project name: » vite-project

选择框架

Select a framework: » - Use arrow-keys. Return to submit.
>   Vanilla
    Vue
    React
    Preact
    Lit
    Svelte
    Others

选择项目语言

Select a variant: » - Use arrow-keys. Return to submit.
>   TypeScript
    JavaScript
    Customize with create-vue ↗
    Nuxt ↗

项目构建成功,根据提示进入项目目录,安装依赖

Done. Now run:

  cd vite-project
  npm install
  npm run dev

在这里插入图片描述
安装 qiankun

$ yarn add qiankun # 或者 npm i qiankun -S

src 目录新增 micro-apps.ts 用来注册微应用

registerMicroApps 参数中的 props 用来编写需要传递给微应用的信息,但是 props 中不可以用( name、entry、container、activeRule) 这几个字段名,否则微应用无法收到主应用传递的信息

import { registerMicroApps, start } from 'qiankun';

const lifeCycles = {
    beforeLoad: (app: any) => {
        console.log("before load app.name====>>>>>", app)
        return Promise.resolve(app)
    },
    beforeMount: (app: any) => {
        console.log("before mount app.name====>>>>>", app)
        return Promise.resolve(app)
    },
    afterMount: (app: any) => {
        console.log("after mount app.name====>>>>>", app)
        return Promise.resolve(app)
    }
}

const register = () => {
    registerMicroApps([
        {
            name: 'vueApp',
            entry: '//localhost:8080',
            container: '#custelement',
            activeRule: '/app-vue',
            props: {
                state: 'props-app-vue',
            },
        },
        {
            name: 'reactApp',
            entry: '//localhost:3000',
            container: '#custelement',
            activeRule: '/app-react',
            props: {
                state: 'props-app-react',
            },
        },
        {
            name: 'angularApp',
            entry: '//localhost:4200',
            container: '#custelement',
            activeRule: '/app-angular',
            props: {
                state: 'props-app-angular',
            },
        }
    ], lifeCycles);
}

export default {
    register,
    start,
}

src 目录新增 globalState.ts 用来编写 initGlobalStateinitGlobalState()qiankun 提供的通信 API)

import { initGlobalState } from 'qiankun';
export function globalState() {
    const { onGlobalStateChange, setGlobalState, offGlobalStateChange } = initGlobalState({
        user: 'init-qiankun'
    })

    onGlobalStateChange((value, prev) =>
        console.log('[onGlobalStateChange - master]:', value, prev)
    )

    setGlobalState({
        user: 'vite-project'
    })
    offGlobalStateChange();
}

微应用从生命周期 mount 中获取通信方法,微应用中只能修改已存在的一级属性(eg: 主应用 setGlobalState ({ user: ‘’ }),微应用只能设置{ user: ‘’ })

export function mount(props) {
  props.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    console.log(state, prev);
  });

  props.setGlobalState({ user: 'react project state' });
}

注意:主应用除了微应用之外,如果还包含有新的业务组件,那么就需要配置对应路由,但是微应用存放容器 container: '#custelement' 和 <router-view /> ,应该处同一层级;否则当微应用渲染之后在跳转至别的组件,组件无法渲染

<div class="content">
     <router-view />
     <div id="custelement"></div>
</div>

跳转页面使用:history

window.history.pushState({}, '',)

除了 registerMicroApps 之外, qiankun 还支持手动加载微应用 loadMicroApp(eg:可以在某个组件挂载微应用)

<template>
    <div>
        <div id="microElemnet"> </div>
    </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'
import { loadMicroApp } from 'qiankun'

var microApp: any = null

onMounted(() => {
    microApp = loadMicroApp({
        name: 'vueApp',
        entry: '//localhost:8080',
        container: '#microElemnet',
    })
})

// 卸载微应用
onUnmounted(() => {
    if (microApp) {
        microApp.unmount()
    }
})
</script>

注意:手动加载微应用时,微应用的 window.__POWERED_BY_QIANKUN__ 也需要与之对应

// 假设当前组件路径为 

http://localhost:8888/nav/list 

// 微应用 window.__POWERED_BY_QIANKUN__

base: window.__POWERED_BY_QIANKUN__ ? '/nav/list' : '/',

使用 loadMicroApp 手动加载微应用,页面跳转用路由,不需要使用 history

二、微应用 react

安装脚手架

npm install -g create-react-app

创建项目

npx create-react-app react-project

项目构建成功,根据提示进入项目目录,启动项目

 cd react-project
 npm start

src 目录新增 public-path.js 文件,在入口文件最顶部引入 public-path.js

if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

设置 history 模式路由的 base

<BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? '/app-react' : '/'}>

入口文件 index.js 修改,为了避免根 id #root 与其他的 DOM 冲突,需要限制查找范围

import './public-path';
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

var root = null
function render(props) {
    console.log(ReactDOM)
    const { container } = props;
    root = container ? ReactDOM.createRoot(container.querySelector('#root')) : ReactDOM.createRoot(document.querySelector('#root'))
    root.render(
        <React.StrictMode>
            <App />
        </React.StrictMode>
    );
}

if (!window.__POWERED_BY_QIANKUN__) {
    render({});
}

export async function bootstrap() {
    console.log('[react16] react app bootstraped');
}

export async function mount(props) {
    console.log('[react16] props from main framework', props);

    props.onGlobalStateChange((state, prev) => {
        // state: 变更后的状态; prev 变更前的状态
        console.log(state, prev);
    });

    props.setGlobalState({ user: 'react project state' });


    render(props);
}

export async function unmount(props) {
    root.unmount()
}

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

修改 webpack 配置

安装插件 react-app-rewired

npm i react-app-rewired

根目录新增 config-overrides.js

const { name } = require('./package');

module.exports = {
    webpack: (config) => {
        config.output.library = `${name}-[name]`;
        config.output.libraryTarget = 'umd';
        // config.output.jsonpFunction = `webpackJsonp_${name}`;
        config.output.globalObject = 'window';

        return config;
    },

    devServer: (_) => {
        const config = _;

        config.headers = {
            'Access-Control-Allow-Origin': '*',
        };
        config.historyApiFallback = true;
        config.hot = false;
        config.watchContentBase = false;
        config.liveReload = false;

        return config;
    },
};

修改 package.json

-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
-   "eject": "react-scripts eject"

启动项目, public-path.js__ webpack_public_path__ 未定义错误

在这里插入图片描述
这是 eslint 的问题, webpack_public_path 不是全局变量所导致的

解决方式 :子应用 package.json 文件中 eslintConfig 配置全局变量,重起服务

"eslintConfig": {
    ...,
    "globals": {
      "__webpack_public_path__": true
    }
}

三、微应用 vue

安装脚手架

npm install -g @vue/cli

创建项目

vue create vue-project

选择手动配置

Vue CLI v5.0.8
? Please pick a preset:             // 选择配置
  Default ([Vue 3] babel, eslint)  // vue2 默认配置
  Default ([Vue 2] babel, eslint)  // vue3 默认配置
> Manually select features         // 手动配置

项目配置(按空格键选择或取消选择)

 Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
 (*) Babel                               // 代码 es6 转 es5
 ( ) TypeScript                          // TypeScript
 ( ) Progressive Web App (PWA) Support   
 (*) Router                              // 路由
>(*) Vuex                                // Vuex
 (*) CSS Pre-processors                  // css 预处理器
 (*) Linter / Formatter                  // eslint 代码格式规范
 ( ) Unit Testing                        // 单元测试
 ( ) E2E Testing                         // 端到端测试

选择 vue 版本

Choose a version of Vue.js that you want to start the project with
  3.x
> 2.x 

第二步如果选择路由,将会有这一步,是否用 history 模式创建路由

Use history mode for router? (Requires proper server setup for index fallback in production) No

第二步如果选择CSS预处理器,将会有这一步,选择CSS预处理器

Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
> Sass/SCSS (with dart-sass)
  Less
  Stylus  

语法检查工具

Pick a linter / formatter config: (Use arrow keys)
> ESLint with error prevention only
  ESLint + Airbnb config
  ESLint + Standard config
  ESLint + Prettier  

什么时候校验代码格式

Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
>(*) Lint on save              // 保存代码时
 ( ) Lint and fix on commit    // 提交代码时

Babel、ESLint 等配置文件存放位置

Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files   // 独立文件放置
  In package.json             // 放在package.json里

是否当前项目配置作为后续项目的预设?

Save this as a preset for future projects? (y/N) N 

项目构建成功,根据提示进入项目目录,启动项目

 cd vue-project
 npm run serve

在这里插入图片描述
src 目录新增 public-path.js 文件,在入口文件最顶部引入 public-path.js

if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

修改路由, router/index.js

import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'

const routes = [
    {
        path: '/',
        redirect: '/home'
    },
    {
        path: '/home',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: AboutView
    }
]

export default routes

修改入口文件 main.js

import './public-path';
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import routes from './router'

Vue.use(VueRouter)

Vue.config.productionTip = false

let router = null;
let instance = null;
function render(props = {}) {
    const { container } = props;
    router = new VueRouter({
        base: window.__POWERED_BY_QIANKUN__ ? '/app-vue' : '/',
        mode: 'history',
        routes,
    });

    instance = new Vue({
        router,
        render: (h) => h(App),
    }).$mount(container ? container.querySelector('#app') : '#app');
}

// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
    render();
}

export async function bootstrap() {
    console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
    console.log('[vue] props from main framework', props);
    props.onGlobalStateChange &&
        props.onGlobalStateChange(
            (value, prev) =>
                console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev),
            true
        )
    props.setGlobalState &&
        props.setGlobalState({
            user: 'vue-project'
        })
    render(props);
}
export async function unmount() {
    instance.$destroy();
    instance.$el.innerHTML = '';
    instance = null;
    router = null;
}

打包配置修改 vue.config.js

const { defineConfig } = require('@vue/cli-service')
const { name } = require('./package');
module.exports = defineConfig({
    transpileDependencies: true,
    devServer: {
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    },
    configureWebpack: {
        output: {
            library: `${name}-[name]`,
            libraryTarget: 'umd', // 把微应用打包成 umd 库格式
            // jsonpFunction: `webpackJsonp_${name}`,  // webpack5不兼容  npm i webpack@4.44.0 可以下载低版本
            globalObject: 'window'
        },
    },
})

四、微应用 angular

安装脚手架

npm install -g @angular/cli

查是否安装成功

ng v
ng version

在这里插入图片描述
创建项目

ng new angular-project

注意: 创建的时候有可能会报错,类似下面这种, 如果没有请忽略;

The Angular CLI requires a minimum Node.js version of either v14.2.0,v16.13 or v18.10.

表示本地 node 和 Angular 版本不对应, 根据提示下载对应版本就行

在这里插入图片描述

是否添加路由

Would you like to add Angular routing? Yes

选择 CSS 预编译器

Which stylesheet format would you like to use?
  CSS
> SCSS   [ https://sass-lang.com/documentation/syntax#scss                ]
  Sass   [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]
  Less   [ http://lesscss.org   

项目构建成功,切换到项目目录,启动项目

 cd angular-project
 ng serve --open

src 目录新增 public-path.js 文件,在入口文件最顶部引入 public-path.js

if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

设置 history 模式路由的 basesrc/app/app-routing.module.ts 文件

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { APP_BASE_HREF } from '@angular/common';

const routes: Routes = [];

declare const window: any;

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
    providers: [{ provide: APP_BASE_HREF, useValue: window.__POWERED_BY_QIANKUN__ ? '/app-angular' : '/' }]
})
export class AppRoutingModule { }

修改入口文件,src/main.ts 文件

import './public-path';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { NgModuleRef } from '@angular/core';
import { AppModule } from './app/app.module';

let app: void | NgModuleRef<AppModule>;
async function render() {
    app = await platformBrowserDynamic()
        .bootstrapModule(AppModule)
        .catch((err) => console.error(err));
}

if (!(window as any).__POWERED_BY_QIANKUN__) {
    render();
}

export async function bootstrap(props: Object) {
    console.log(props);
}

export async function mount(props: Object) {
    render();
}

export async function unmount(props: Object) {
    console.log(props);
    // @ts-ignore
    app.destroy();
}

修改 webpack 打包配置

先安装 @angular-builders/custom-webpack 插件,注意:angular 9 项目只能安装 9.x 版本,angular 10 项目可以安装最新版。

npm i @angular-builders/custom-webpack@9.2.0 -D

在根目录增加 custom-webpack.config.js

const appName = require('./package.json').name;
module.exports = {
    devServer: {
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    },
    output: {
        library: `${appName}-[name]`,
        libraryTarget: 'umd',
        // jsonpFunction: `webpackJsonp_${appName}`,
    },
};

修改 angular.json,将 [packageName] > architect > build > builder[packageName] > architect > serve > builder 的值改为我们安装的插件,将我们的打包配置文件加入到 [packageName] > architect > build > options

- "builder": "@angular-devkit/build-angular:browser",
+ "builder": "@angular-builders/custom-webpack:browser",
  "options": {
+    "customWebpackConfig": {
+      "path": "./custom-webpack.config.js"
+    }
  }
- "builder": "@angular-devkit/build-angular:dev-server",
+ "builder": "@angular-builders/custom-webpack:dev-server",

解决 zone.js 的问题

父应用 安装zone.js

npm i zone.js

父应用 引入,需要在import qiankun 之前引入

import 'zone.js/dist/zone';

微应用src/polyfills.ts 里面的引入 zone.js 代码删掉(新版本已经没有 polyfills.ts 文件了,修改 angular.json,将 [packageName] > architect > build > options > polyfills 配置为空即可 )

在微应用的 src/index.html 里面的 <head> 标签加上下面内容,微应用独立访问时使用

<!-- 也可以使用其他的CDN/本地的包 -->
<script src="https://unpkg.com/zone.js" ignore></script>

修正 ng build 打包报错问题,修改 tsconfig.json 文件

- "target": "es2015",
+ "target": "es5",
+ "typeRoots": [
+   "node_modules/@types"
+ ],

为了防止主应用或其他微应用也为 anuglar 时, <app-root></app-root> 会冲突的问题,建议给 <app-root> 加上一个唯一的 id ,比如说当前应用名称

src/index.html :

- <app-root></app-root>
+ <app-root id="angular15"></app-root>

src/app/app.component.ts :

- selector: 'app-root',
+ selector: '#angular15 app-root',

五、项目地址

项目地址:https://github.com/aibuijn/qiankun

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/540669.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HIVE建表详细教程

1. 注意事项如下 1.1 分区字段 可以有多个分区字段&#xff0c;一般以时间维度来建立分区&#xff0c;也可以再加其他字段。以业务场景为提前条件&#xff0c;来设定分区的字段。 从业务角度理解&#xff0c;分区字段可理解为业务数据的一部分&#xff0c;作为业务查询…

Bed Bath and Beyond EDI 需求分析

Bed Bath and Beyond&#xff08;Bed Bath and Beyond&#xff09;是一家美国的家居用品零售商&#xff0c;成立于1971年&#xff0c;总部位于新泽西州Union。该公司在美国、加拿大和墨西哥拥有超过1500家门店。其产品涵盖了床上用品、浴室用品、厨房用品、家居装饰等领域&…

Win11怎么添加用户?我们都知道系统一般默认是administraor用户

Win11怎么添加用户&#xff1f;我们都知道系统一般默认是administraor用户&#xff0c;但如果你还想添加新用户的话&#xff0c;那么可以参考以下操作哦&#xff0c;步骤简单&#xff0c;安全有效&#xff0c;我们一起来学习下吧。 具体操作如下&#xff1a; 1、首先&#xff0…

NXP MCUXPresso - cc1plus.exe: out of memory allocating 65536 bytes

文章目录 NXP MCUXPresso - cc1plus.exe: out of memory allocating 65536 bytes概述实验结论补充END NXP MCUXPresso - cc1plus.exe: out of memory allocating 65536 bytes 概述 在尝试迁移 openpnp - Smoothieware project 从gcc命令行 MRI调试方式 到NXP MCUXpresso工程…

iscsi删除已失效的链路

有套rac环境&#xff0c;主机连接存储使用的iscsi方式&#xff0c;使用了一段时间&#xff0c;客户感觉网络设计不合理&#xff0c;需要调整网段vlan和ip地址 首先关闭实例和集群&#xff0c;调整存储端和主机端的ip地址和vlan&#xff0c;调整后可以ping通&#xff0c;使用如…

隐藏自己的真实ip

本文转载于&#xff1a; https://blog.csdn.net/csdnmmd/article/details/126952312 1.ip查看 https://mp.weixin.qq.com/s/zs2clrxQts9f7pK6CQ2oOw 1.1 无隧道的情况 当前从138和请求ipinof.io上可以查到目前我的ip地址为真实的ip&#xff1a; 访问下面这个地址之后&#xff…

SVG矢量图怎么做?

SVG 矢量图是一种可缩放的图像格式&#xff0c;基于 XML 的标记语言。它可以用于描述二维矢量图形&#xff0c;并且具有数百种功能&#xff0c;能够帮助你创建出色的网站。SVG矢量图怎么做&#xff1f;在本教程中&#xff0c;我们将学习如何使用SVG矢量图编辑器——即时设计制作…

一种基于非均匀分簇和建立簇间路由的算法的无线传感器网络路由协议(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 本文准备了一种路由方法&#xff0c;该方法使传感器通过有效地使用能量将数据从发送方加载到接收器&#xff0c;因为它在 LEAC…

安装Ubuntu18.04双系统、干净卸载,并在Ubuntu系统中安装CARLA模拟器

Ubuntu系统安装 Ubuntu系统安装参照流程 Ubuntu 双系统安装流程_ubuntu双系统_地球被支点撬走啦的博客-CSDN博客 Ubuntu系统卸载 1.将开机启动项设置默认为Windows&#xff0c;进入BIOS设置界面调整BootDevice中Windows和Ubuntu的顺序&#xff0c;将Windows调整在Ubuntu前边…

封神之作!超火Java面试突击手册一周内转发2.4W次,最终被所有大厂封杀

前言 本文是为了帮大家快速回顾了Java中知识点&#xff0c;这套面试手册涵盖了诸多Java技术栈的面试题和答案&#xff0c;相信可以帮助大家在最短的时间内用作面试复习&#xff0c;能达到事半功倍效果。 本来想将文件上传到github上&#xff0c;但由于文件太大有的都无法显示…

OpenPCDet系列 | 5.4.1 DenseHead中的AnchorGenerator锚框生成模块

文章目录 AnchorGenerator模块AnchorGenerator.generate_anchors函数 AnchorGenerator模块 首先&#xff0c;根据点云场景将其划分为一个个grid&#xff0c;这个grid size是可以通过配置文件设定的点云场景方位和voxel大小计算出来的。 POINT_CLOUD_RANGE: [0, -39.68, -3, 6…

研发工程师玩转Kubernetes——部署应用

Kubernetes是容器的管理编排工具&#xff0c;而容器则是程序的载体。我们先在Docker上部署应用&#xff0c;然后再在kubernetes上部署&#xff0c;并对它们进行对比学习。 Docker部署应用 查看运行中的容器 docker ps可以看到下面的表头&#xff0c;此时没有一个运行中的容器…

图片压缩指定大小,让您的图片高效而优美

在现代社会中&#xff0c;图片是我们不可或缺的一部分&#xff0c;在各行业中都有着非常重要的作用。但是&#xff0c;大尺寸的图片不仅会占用过多的存储空间&#xff0c;还会导致网页或应用程序的加载速度变慢。因此&#xff0c;将图片压缩到指定大小是一个必要的步骤。 图片…

文档管理-gitlab+markdown网页插件

特点 使用git进行版本管理&#xff0c;本地编辑使用Typora。使用gitlab进行权限管理可以在线阅读通过Markdown在线阅读插件实现&#xff0c;可显示目录显示与链接跳转&#xff0c;界面优于自带的wiki。 与其他方式对比 gitlab的wiki&#xff1a;显示界面效果不好&#xff0c…

书籍《脆弱的繁华》读后感

前几周看完了《脆弱的繁华》这本书&#xff0c;这本书当时是公司组织的一次活动&#xff0c;邀请书籍原作者&#xff0c;张程对书籍进行了讲解&#xff0c;同时这本书也是在此次活动中免费赠送的&#xff0c;作者对于书籍做了一些说明&#xff0c;并且对一些问题也进行了探讨&a…

Azkaban 集群模式部署

文章目录 Azkaban 集群模式部署一、配置Mysql Azkaban 集群模式部署 将这三个包&#xff0c;上传到hadoop102&#xff0c;第一个是azkaban需要的建表语句 这三个解压到 /opt 目录下 输入命令&#xff1a;tar -zxvf azkaban-db-3.84.4.tar.gz -C /opt/ 输入命令&#xff1a;ta…

spring注册beanDefinition

代码使用springboot测试 1.ConfigurationClassPostProcessor 构造context时会创建reader。 构造reader时会创建processor。 最关键是第一个&#xff0c;类型是ConfigurationClassPostProcessor。 AbstractApplicationContext类的refresh方法的invokeBeanFactoryPostProcesso…

Node输出日志的正确姿势

背景 每个程序员都喜欢在有问题的代码中插入一些日志的方法来帮助调试程序&#xff0c;比如System.out.println或console.log。解决后&#xff0c;就会将这些语句删除&#xff0c;周而复始。 但是通过系统日志输出的日志格式都是这种&#xff1a; // output console.log(&quo…

TensoRF-张量辐射场论文笔记

TensoRF-张量辐射场论文笔记_什度学习的博客-CSDN博客 注释代码: https://github.com/xunull/read-TensoRF 官方源码&#xff1a;https://github.com/apchenstu/TensoRF Install environment conda create -n TensoRF python3.8 conda activate TensoRF pip install torch t…

HTTPTomcatServlet学习

HTTP&Tomcat 今日目标&#xff1a; 了解JavaWeb开发的技术栈理解HTTP协议和HTTP请求与响应数据的格式掌握Tomcat的使用掌握在IDEA中使用Tomcat插件理解Servlet的执行流程和生命周期掌握Servlet的使用和相关配置 1. Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网&…