簡體   English   中英

如何配置 webpack 以顯示帶有打字稿的反應組件

[英]How do I configure webpack to display react component with typescript

所以我試圖讓我的節點項目呈現一個簡單的反應組件,我正在使用 webpack 進行捆綁

我的 package.json 將主要入口點設置為 webpack.config.js 並有一個 srcipt 來運行 webpack-dev-server。 這是我的 package.json :

{
"name": "@ruler-mobility/ruler",
"_comment": "main set to webpack's bundle file(home.tsx). this attr only explain main's purpose, delete it in the next merge ",
"main": "webpack.config.js",
"dependencies": {
    "@types/jest": "^25.1.3",
    "axios": "^0.19.1",
    "chalk": "^3.0.0",
    "compression": "^1.7.4",
    "cors": "^2.8.5",
    "errorhandler": "^1.5.1",
    "express": "^4.17.1",
    "express-session": "^1.16.2",
    "geolocation-utils": "^1.2.2",
    "jest": "^25.1.0",
    "jsonwebtoken": "^8.5.1",
    "node-sass": "^4.13.1",
    "numeral": "^2.0.6",
    "query-string": "^6.11.0",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "ts-jest": "^25.2.1",
    "typecast": "0.0.1",
    "winston": "^3.2.1"
},
"devDependencies": {
    "@types/compression": "^1.0.1",
    "@types/concurrently": "^4.1.0",
    "@types/cors": "^2.8.6",
    "@types/errorhandler": "^0.0.32",
    "@types/express": "^4.17.1",
    "@types/express-session": "^1.15.14",
    "@types/jsonwebtoken": "^8.3.6",
    "@types/node": "^12.12.25",
    "@types/numeral": "0.0.26",
    "@types/react": "^16.9.23",
    "@types/react-dom": "^16.9.5",
    "@types/ts-nameof": "^4.2.1",
    "@types/winston": "^2.4.4",
    "@typescript-eslint/eslint-plugin": "^2.18.0",
    "@typescript-eslint/parser": "^2.18.0",
    "cache-loader": "^4.1.0",
    "concurrently": "^5.0.0",
    "dotenv-webpack": "^1.7.0",
    "eslint": "^6.8.0",
    "eslint-config-prettier": "^6.9.0",
    "eslint-config-standard": "^14.1.0",
    "eslint-import-resolver-typescript": "^2.0.0",
    "eslint-loader": "^3.0.3",
    "eslint-plugin-autofix": "0.0.9",
    "eslint-plugin-import": "^2.20.0",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-no-use-extend-native": "^0.4.1",
    "eslint-plugin-node": "^11.0.0",
    "eslint-plugin-prettier": "^3.1.2",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-react": "^7.18.0",
    "eslint-plugin-react-hooks": "^1.7.0",
    "eslint-plugin-sonarjs": "^0.5.0",
    "eslint-plugin-sort-imports-es6-autofix": "^0.5.0",
    "eslint-plugin-standard": "^4.0.1",
    "eslint-plugin-switch-case": "^1.1.2",
    "fork-ts-checker-webpack-plugin": "^4.0.4",
    "jest-extended": "^0.11.4",
    "nodemon": "^1.19.2",
    "prettier": "^1.19.1",
    "ts-loader": "^6.2.1",
    "ts-nameof": "^4.2.2",
    "ts-node": "^8.6.2",
    "tsconfig-paths-webpack-plugin": "^3.2.0",
    "typescript": "^3.7.5",
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.3",
    "webpack-merge": "^4.2.2",
    "webpack-node-externals": "^1.7.2"
},
"repository": {
    "type": "git",
    "url": "git+https://bitbucket.org/ruler-mobility/ruler.git"
},
"scripts": {
    "start": "webpack-dev-server",
    "build": "webpack --mode=production",
    "lint": "eslint . --quiet --fix --ext js,jsx,ts,tsx",
    "test": "jest --forceExit --coverage --verbose",
    "watch-test": "npm run test -- --watchAll",
    "stop-win": "Taskkill /IM node.exe /F",
    "stop-linux": "killall node"
},
"version": "1.0.0"
 }

我的 webpack.config.js 將 Home.tsx 設置為要捆綁的內容和父文件夾中輸出文件路徑的入口點。 這是它的外觀:

const path = require('path');
const chalk = require('chalk');
const merge = require('webpack-merge');
const Dotenv = require('dotenv-webpack');
 const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
 const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
 const nodeExternals = require('webpack-node-externals');
 const tsNameof = require('ts-nameof');
 const { PORT } = process.env;

module.exports = (env = {}, argv = {}) => {
const { mode } = argv;
const production = mode === 'production';
const development = !production;

console.log(
    chalk.blue(`The current build process is running in ${chalk.underline((production ? 'production' : 'development').toUpperCase())} mode`)
);

return merge(
    {
        devtool: production ? 'eval' : 'cheap-module-eval-source-map'
    },
    development && {
        optimization: {
            removeAvailableModules: false,
            removeEmptyChunks: false,
            splitChunks: false
        },
        output: {
            pathinfo: false
        }
    },
    {
        context: __dirname,
        target: 'node',
  externals: [nodeExternals()],
  //set the entry point to our app(the front-end)
        entry: path.resolve(__dirname, './front-end/components/Home.tsx'),
        module: {
            rules: [
                {
                    test: /\.tsx?$/,
                    use: [
                        'cache-loader',
                        {
                            loader: 'ts-loader',
                            options: {
                                transpileOnly: true,
                                happyPackMode: true
                            }
                        },
                        {
                            loader: 'eslint-loader',
                            options: {
                                fix: true,
                                quiet: true,
                                // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
                                getCustomTransformers: () => ({ before: [tsNameof] })
                            }
                        }
                    ],
                    exclude: /node_modules/
                }
            ]
        },
        plugins: [new Dotenv(), new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true })],
        resolve: {
            extensions: ['.js', '.jsx', '.ts', '.tsx'],
            plugins: [
                new TsconfigPathsPlugin({
                    configFile: 'tsconfig.json'
                })
            ]
  },
  // output set's the path for front-end bundle file
        output: {
    path: path.resolve(__dirname, 'front-end/dist'),
            filename: 'home.js'

        },
        devServer: {
            contentBase: path.join(__dirname, 'front-end/dist'),
            compress: true,
            open: true,
            hot: true,
            port: PORT || 3000
        }
    }
);
 };

所以我希望 webpack 將我的文件(將包括我的 Home.tsx 使用的所有內容)捆綁在front-end/dist目錄中,名稱為home.js

這是我設置Home 我在路徑front-end/index.html中有一個索引 html,其中包含:

<body>
    <div class="container"></div>
    <h1>Hello</h1>
    <script src="/front-end/dist/home.js"></script>
</body>

還有我的 Home.jsx:

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

const ROOT = document.querySelector('.container');
ReactDOM.render(<h1>HELLO 2</h1>, ROOT);

當我運行npm run script start並打開 localhost:3000 時,我的瀏覽器顯示了front-end/dist目錄中的所有文件,即home.js文件。 它不應該加載 Home.tsx 文件,因為這是我在 webpack 中設置的入口點。 如何配置 webpack 以在根目錄下顯示“home.tsx”,即 localhost:3000。

加上這里我的 tsconfig 文件:

 {
"compilerOptions": {
    "alwaysStrict": true,
    "module": "commonjs",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "jsx": "react",
    "lib": ["es6", "dom"],
    "target": "es6",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
        "*": ["node_modules/*"],
        "@ruler": ["src", "packages"],
        "@ruler/*": ["src/*", "packages/*"],
        "@ruler/configs": ["configs"],
        "@ruler/configs/*": ["configs/*"],
        "@ruler/test": ["test"],
        "@ruler/test/*": ["test/*"],
        "@ruler/types": ["types"],
        "@ruler/types/*": ["types/*"]
    }
},
"exclude": ["node_modules", "**/*.spec.ts"]
}

文件結構:

 Project
       |
       +-- package.json
       |    
       +-- tsconfig.json
       |   
       +-- webpack.config.js
       |   
       +-- front-end 
       |           |  
                   +-- components
                   |            |
                   |             +-- Home.tsx
                   |
                   +--index.html

注意:這些只是用於設置的文件,項目包含更多但我不需要提及它們

在我看來,您指的是錯誤的文件。 因為您提到了.tsx文件,但您的實際文件是.jsx文件。 所以我覺得你應該添加.jsx來代替:

entry: path.resolve(__dirname, './front-end/components/Home.jsx')

或者您應該將文件重命名為Home.tsx

首先,如果你需要為你的 webpack 配置添加 typescript 支持,你需要添加 '.ts' 和 '.tsx' 作為可解析的擴展名 abd 為 ts 文件支持添加特定的加載器規則。

 resolve: {
        extensions: [".ts", ".tsx"]
    },
 module: {
        rules: [
            {
                test: /\.ts(x?)$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "ts-loader"
                    }
                ]
            },
            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            {
                enforce: "pre",
                test: /\.js$/,
                loader: "source-map-loader"
            }
        ]
    },

您的 home.js 是由 webpack 生成的捆綁文件,作為轉換您的入口文件后的輸出,該文件將是您的 Home.jsx 或您的 Home.tsx。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM