varHarrie / varharrie.github.io

:blue_book: Personal blog site based on github issues.
https://varharrie.github.io
MIT License
3.66k stars 548 forks source link

使用parcel配置typescript + react/preact项目 #22

Open varHarrie opened 6 years ago

varHarrie commented 6 years ago

一、安装依赖

# 初始化项目
npm init -y
# 或者
yarn init -y

# 安装开发依赖
npm i --save-dev parcel-bundler typescript tslint

# 安装less(可选)
npm i --save-dev less

# 使用react(二选一)
npm i --save react react-dom react-router react-router-dom history @types/react @types/react-dom @types/react-router @types/react-router-dom @types/history

# 使用preact(二选一)
npm i --save preact preact-router history @types/history

# 创建tsconfig.json(需要npm i -g typescript)
tsc --init

# 打开tsconfig.json并设置:
# "lib": ["es6", "dom"],
# "jsx": "react"

# 创建tslint.json(需要npm i -g tslint)
tslint --init

二、配置script

package.jsonscript字段中添加:

"scripts": {
  "dev": "parcel index.html -p 80",
  "build": "parcel build index.html --public-url ./"
}

三、创建入口文件

创建index.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Hello world</title>
</head>
<body>
  <div id="root"></div>
  <script src="./src/index.tsx"></script>
</body>
</html>

创建src文件夹,在src文件夹中创建index.tsx

import * as React from 'react'
import * as ReactDOM from 'react-dom'

ReactDOM.render(
  <div id='root'>
    hello world
  </div>
, document.getElementById('root'))

// preact使用:
// import * as React from 'preact'
//
// React.render(
//   <div id='root'>
//     hello world
//   </div>
// , document.getElementById('root'))

四、运行项目

npm run start

五、配置tslint(可选)

# 安装tslint-react、tslint-eslint-rules
npm i --save-dev tslint-react tslint-eslint-rules

完整配置文件,rules请根据自己习惯或项目需求自行修改:

{
    "defaultSeverity": "error",
    "extends": [
        "tslint-react",
        "tslint-eslint-rules"
    ],
    "jsRules": {},
    "rules": {
        "align": [true, "parameters", "statements"],
        "ban": false,
        "class-name": true,
        "comment-format": [true, "check-space"],
        "curly": [true, "ignore-same-line"],
        "eofline": false,
        "forin": false,
        "indent": [ true, "spaces" ],
        "interface-name": [true, "always-prefix"],
        "jsdoc-format": true,
        "jsx-alignment": false,
        "jsx-boolean-value": false,
        "jsx-no-lambda": false,
        "jsx-no-multiline-js": false,
        "label-position": true,
        "max-classes-per-file": [false],
        "max-line-length": [ true, 120 ],
        "member-ordering": [true, "public-before-private", "static-before-instance"],
        "no-any": false,
        "no-arg": true,
        "no-bitwise": false,
        "no-console": [false],
        "no-consecutive-blank-lines": [true],
        "no-construct": true,
        "no-debugger": true,
        "no-duplicate-variable": true,
        "no-empty": true,
        "no-empty-interface": false,
        "no-eval": true,
        "no-shadowed-variable": true,
        "no-string-literal": true,
        "no-switch-case-fall-through": true,
        "no-trailing-whitespace": false,
        "no-unused-expression": true,
        "no-unused-variable": true,
        "no-use-before-declare": true,
        "object-curly-spacing": [true, "never"],
        "one-line": [true, "check-catch", "check-else", "check-open-brace", "check-whitespace"],
        "only-arrow-functions": [false],
        "ordered-imports": [false],
        "quotemark": [true, "single"],
        "radix": false,
        "semicolon": [true, "never"],
        "space-before-function-paren": [true],
        "switch-default": true,
        "trailing-comma": [false],
        "triple-equals": [ true, "allow-null-check" ],
        "typedef": [true, "parameter", "property-declaration"],
        "typedef-whitespace": [true, {"call-signature": "nospace", "index-signature": "nospace", "parameter": "nospace", "property-declaration": "nospace", "variable-declaration": "nospace"}],
        "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
        "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type", "check-typecast"]
    },
    "rulesDirectory": []
}

六、热替换

修改入口文件index.tsx

import * as React from 'react'
import * as ReactDOM from 'react-dom'

import App from './App'

declare const module: any

const render = (Component: React.ComponentClass) => {
  ReactDOM.render(
    <Component/>,
    document.getElementById('root')
  )
}

render(App)

if (module.hot) {
  module.hot.accept(() => {
    const NextApp = require('./App').default
    render(NextApp)
  })
}