0

根据以下站点,我认为我可以在一个编译中同时使用 preact 和 react。但是当我试图在一个编译中一起使用这些库时,就会发生冲突。我认为 preact 和 react 仍然有全局 JSX 命名空间,所以暂时不能混用。如果我的配置有误,请告诉我。

https://blogs.msdn.microsoft.com/typescript/2018/03/27/announcing-typescript-2-8/#jsx-namespace-resolution

JSX 通过 JSX 工厂解析 目前,当 TypeScript 使用 JSX 时,它会查找全局 JSX 命名空间来查找某些类型(例如,“JSX 组件的类型是什么?”)。在 TypeScript 2.8 中,编译器将尝试根据 JSX 工厂的位置查找 JSX 命名空间。例如,如果您的 JSX 工厂是 React.createElement,TypeScript 将尝试首先解析 React.JSX,然后从当前范围内解析 JSX。

这在混合和匹配不同库(例如 React 和 Preact)或特定库的不同版本(例如 React 14 和 React 16)时会很有帮助,因为将 JSX 命名空间放在全局范围内可能会导致问题。

这是我的测试项目

  • 操作系统:Windows 10 64
  • 节点:6.9.5
  • npm:3.10.10
  • tsc:2.8.3
  • 网络包:4.6.0
  • webpack-cli:2.0.15

目录结构

  • 距离
  • 源代码
    • 成分
      • PreactUser.tsx
      • 反应用户.tsx
    • 索引.tsx
  • 索引.html
  • 包.json
  • tsconfig.json
  • webpack.config.json

src/components/PreactUser.tsx (第一行: /** @jsx h */)

import {h, Component} from 'preact';

export interface HelloWorldProps {
    name: string
}

export default class PreactUserComp extends Component<HelloWorldProps, any> 
{
    render (props: HelloWorldProps) {
        return <h1>Hello {props.name}!</h1>
    }
}

原来第一行是 /** @jsx h */. 但是此编辑器无法将其识别为正确的代码。

src/components/ReactUser.tsx (第一行: /** @jsx React.createElement */)

import * as React from "react";

export interface HelloProps { firstName: string; lastName: string; }

interface Person {
    firstName: string;
    lastName: string;
}
class User implements Person {
    firstName: string;
    lastName: string;
    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
function formatName(user:User): string {
    return user.firstName + ' ' + user.lastName;
}

export class ReactUserComp extends React.Component<HelloProps, {}> {
    render() {
        return <h1>Hello {this.props.firstName} {this.props.lastName}!</h1>;
    }
}

src/index.tsx (第一行: /** @jsx h */)

import { h, render } from 'preact';
import PreactUserComp from './components/PreactUser';

render(<PreactUserComp name="Preact" />, document.querySelector('#app'));

包.json

{
    "name": "typescript-preact-react",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC",
    "dependencies": {
        "@types/react": "^16.3.13",
        "@types/react-dom": "^16.0.5",
        "react": "^16.3.2",
        "react-dom": "^16.3.2",
        "preact": "^8.2.7",
        "ts-loader": "^4.2.0",
        "typescript": "^2.8.3",
        "webpack": "^4.6.0"
    },
    "devDependencies": {
        "typescript": "^2.8.3",
        "webpack": "^4.6.0",
        "webpack-cli": "^2.0.15"
    }
}

tsconfig.json

{
    "compilerOptions": {
        "sourceMap": true,
        "module": "commonjs",
        "jsx": "react",
        "target": "es5"
    },
    "include": [
        "src/*.ts",
        "src/*.tsx"
    ]
}

webpack.config.js

var path = require('path');

module.exports = {
    devtool: 'source-map',
    entry: './src/index.tsx',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'app.js'
    },
    resolve: {
        extensions: ['.ts', '.tsx']
    },
    module: {
        rules: [
        {
            test: /\.tsx?$/,
            exclude: /node_modules/,
            loaders: ['ts-loader']
        }
        ]
    }
}

索引.html

<div id="app"></div>
<script src="dist/app.js"></script>

本来 index.html 的代码比较少,但是这个编辑器不能识别它是正确的代码,所以我总结了代码。

4

1 回答 1

0

这确实是问题所在。为了与使用React一起Preact使用typescript,您需要拥有自己的声明文件(typings.d.ts)。

我不完全知道应该如何做的细节。但我想为我的项目设置类似的设置,并找到了一个试图解决这个问题的 Github 项目。

链接:Hotell/react-preact-typescript-interop

我还没试过。但我认为这会在一定程度上帮助你。

于 2018-10-04T10:32:27.583 回答