模块解析失败:React Component Render上出现意外令牌

时间:2019-01-01 11:29:39

标签: reactjs typescript webpack configuration babel

我正在尝试使用Typescript配置React(仅用于类型检查),Babel用于所有代码转换,Jest用于测试,ESLint用于代码检查以及其他工具。请检查下面所有文件的回购链接。

我遵循Kent C. Dodds和以下教程来添加带有Typescript的webpack:https://blog.wax-o.com/2018/05/webpack-loaders-babel-sourcemaps-react-hot-module-reload-typescript-modules-code-splitting-and-lazy-loading-full-tutorial-to-transpile-and-bundle-your-code/

似乎所有这些工具都可以一起使用,因为构建在某种程度上确实适用于TypeScript文件,但是开发服务器却没有,并且现在都无法使用。

由于我是完全的初学者,我希望有更多经验丰富的双眼来看看配置。

错误消息:

PS D:\server\www\apache24_29\htdocs\react-boilerplate> npm run build

> react-boilerplate@1.0.0 build D:\server\www\apache24_29\htdocs\react-boilerplate
> webpack --env.NODE_ENV=production

Start build for NODE_ENV:  production
clean-webpack-plugin: D:\server\www\apache24_29\htdocs\react-boilerplate\webpackConfig\dist has been removed.
Hash: a14d15aa8f5505a1657a
Version: webpack 4.28.3
Time: 200ms
Built at: 2019-01-01 12:00:02
 2 assets
Entrypoint main = index.js sourcemaps/main.js.map
[0] ./src/index.tsx 262 bytes {0} [built] [failed] [1 error]
ERROR in ./src/index.tsx 6:16
Module parse failed: Unexpected token (6:16)
You may need an appropriate loader to handle this file type.| import { HelloComponent } from "./hello";
|
> ReactDOM.render(<HelloComponent />, document.getElementById("root"));
|
Webpack Bundle Analyzer saved report to D:\server\www\apache24_29\htdocs\react-boilerplate\dist\report.html
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! react-boilerplate@1.0.0 build: `webpack --env.NODE_ENV=production`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the react-boilerplate@1.0.0 build script.npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\...\AppData\Roaming\npm-cache\_logs\2019-01-01T11_00_03_174Z-debug.log

我用当前版本创建了一个存储库。一切都在进行中: https://github.com/ethernal/react-boilerplate

我也在这里发布配置。

package.json

{
    "name"       : "react-boilerplate",
    "version"    : "1.0.0",
    "description": "React Boilerplate with Typescript, Babel, Jest, EsLint, Prettier, Styled Components, React Testig Library, Webpack, Webpack Dev Server",
    "main"       : "index.tsx",
    "scripts"    : {
        "format"           : "prettier \"**/*.(js|ts|tsx|jsx)\" --write",
        "lint"             : "eslint . --ext \".js,.ts,.tsx\"",
        "typecheck"        : "tsc",
        "test"             : "jest --watch",
        "cover"            : "jest --coverage",
        "start"            : "babel-node --extensions '.ts,.tsx' index.ts",
        "build"            : "webpack --env.NODE_ENV=production",
        "server-no-reaload": "webpack-dev-server --env.NODE_ENV=development",
        "server"           : "nodemon --watch webpack.config.ts -x webpack-dev-server --  --env.NODE_ENV=development"
    },
    "author"      : "",
    "license"     : "ISC",
    "dependencies": {
        "@reach/router"                 : "^1.2.1",
        "babel-plugin-styled-components": "^1.10.0",
        "react"                         : "^16.7.0",
        "react-dom"                     : "^16.7.0",
        "styled-components"             : "^4.1.3"
    },
    "devDependencies": {
        "@babel/cli"                             : "^7.2.3",
        "@babel/core"                            : "^7.2.2",
        "@babel/parser"                          : "^7.2.3",
        "@babel/plugin-proposal-class-properties": "^7.2.3",
        "@babel/plugin-syntax-dynamic-import"    : "^7.2.0",
        "@babel/preset-env"                      : "^7.2.3",
        "@babel/preset-react"                    : "^7.0.0",
        "@babel/preset-typescript"               : "^7.1.0",
        "@types/jest"                            : "^23.3.10",
        "@types/node"                            : "^10.12.18",
        "@types/react"                           : "^16.7.17",
        "@types/react-dom"                       : "^16.0.11",
        "@types/webpack"                         : "^4.4.22",
        "babel-loader"                           : "^8.0.4",
        "clean-webpack-plugin"                   : "^1.0.0",
        "copy-webpack-plugin"                    : "^4.6.0",
        "eslint"                                 : "^5.10.0",
        "eslint-plugin-typescript"               : "^0.14.0",
        "html-minifier"                          : "^3.5.21",
        "jest"                                   : "^23.6.0",
        "jest-runner-eslint"                     : "^0.7.1",
        "jest-runner-tsc"                        : "^1.3.2",
        "nodemon"                                : "^1.18.9",
        "pluggable-babel-eslint"                 : "^0.3.0",
        "prettier"                               : "^1.15.3",
        "react-hot-loader"                       : "^4.6.3",
        "react-testing-library"                  : "^5.4.2",
        "source-map-loader"                      : "^0.2.4",
        "ts-loader"                              : "^5.3.2",
        "ts-node"                                : "^7.0.1",
        "typescript"                             : "^3.2.2",
        "typescript-babel-jest"                  : "^1.0.5",
        "typescript-eslint-parser"               : "^21.0.2",
        "uglifyjs-webpack-plugin"                : "^2.1.1",
        "webpack"                                : "^4.28.3",
        "webpack-bundle-analyzer"                : "^3.0.3",
        "webpack-cli"                            : "^3.1.2",
        "webpack-dev-server"                     : "^3.1.14"
    },
    "jest": {
        "setupFiles": [
            "./jest.config.js"
        ],
        "moduleDirectories": [
            "./node_modules",
            "./src"
        ],
        "moduleFileExtensions": [
            "ts",
            "tsx",
            "js",
            "jsx"
        ],
        "transform": {
            "^.+\\.(js|jsx|ts|tsx)$": "typescript-babel-jest"
        }
    },
    "resolutions": {
        "babel-core": "^7.0.0-bridge.0"
    }
}

webpack的主要配置:

const path = require('path');
const productionConfig = require('./webpackConfig/production');
const developmentConfig = require('./webpackConfig/development');

module.exports = env => {
  if (env.NODE_ENV === 'production')
    return productionConfig(env, path.resolve(__dirname));

  if (env.NODE_ENV === 'development')
    return developmentConfig(env, path.resolve(__dirname));
};

webpack开发配置:

const webpack = require("webpack");

function buildDevelopementConfig(env, dirname) {
    //eslint-disable-next-line no-console
    console.log("Start build for NODE_ENV: ", env.NODE_ENV);

    return {
        entry  : dirname + "/src/index.tsx",
        devtool: "cheap-module-eval-source-map",
        output : {
            path             : dirname + "/dist",
            filename         : "index.js",
            publicPath       : "/",
            sourceMapFilename: "bundle.map"
        },
        mode   : "development",
        resolve: {
            extensions: [".js", ".json", ".ts", ".jsx", ".tsx"],
            alias     : {
                UIComponents: dirname + "/src/components",
                UIAssets    : dirname + "/src/assets"
            }
        },
        devServer: {
            host            : "0.0.0.0",
            contentBase     : dirname + "/src",
            hotOnly         : true,
            overlay         : true,
            publicPath      : "/",
            watchContentBase: false
        },
        module: {
            rules: [
                {
                    test   : /\.(tsx?)$/i,
                    include: dirname + "/src",
                    use    : {
                        loader : "babel-loader",
                        options: {
                            presets: [
                                [
                                    "@babel/preset-env",
                                    {
                                        modules: false,
                                        debug  : true,
                                        target : {
                                            browsers: ["> 0.5%"]
                                        }
                                    }
                                ],
                                "@babel/preset-react",
                                "@babel/typescript"
                            ],
                            plugins: [
                                "babel-plugin-styled-components",
                                "@babel/plugin-syntax-dynamic-import",
                                "@babel/plugin-proposal-class-properties",
                                "react-hot-loader/babel"
                            ]
                        }
                    }
                }
            ]
        },
        plugins: [
            new webpack.NamedModulesPlugin(),
            new webpack.HotModuleReplacementPlugin()
        ]
    };
}

module.exports = buildDevelopementConfig;

Webpack生产配置:

const webpack = require("webpack");
const CleanWebpackPlugin       = require("clean-webpack-plugin");
const CopyWebpackPlugin        = require("copy-webpack-plugin");
const HTMLMinifier             = require("html-minifier");
const UglifyJsPlugin           = require("uglifyjs-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");

function buildProductionConfig(env, dirname) {
    //eslint-disable-next-line no-console
    console.log("Start build for NODE_ENV: ", env.NODE_ENV);

    return {
        entry : dirname + "/src/index.tsx",
        output: {
            path             : dirname + "/dist",
            filename         : "index.js",
            publicPath       : "/",
            sourceMapFilename: "bundle.map"
        },
        mode   : "production",
        resolve: {
            extensions: [".js", ".json", ".ts", ".jsx", ".tsx"],
            alias     : {
                UIComponents: dirname + "/src/components",
                UIAssets    : dirname + "/src/assets"
            }
        },
        module: {
            rules: [
                {
                    test   : /\.(js|jsx|ts|tsx?)$/i,
                    include: dirname + "/src",
                    use    : {
                        loader : "babel-loader",
                        options: {
                            presets: [
                                [
                                    "@babel/preset-env",
                                    {
                                        modules: false,
                                        debug  : true,
                                        target : {
                                            browsers: ["cover 99%"]
                                        }
                                    }
                                ],
                                "@babel/preset-react",
                                "@babel/typescript"
                            ],
                            plugins: [
                                "babel-plugin-styled-components",
                                "@babel/plugin-syntax-dynamic-import",
                                "@babel/plugin-proposal-class-properties"
                            ]
                        }
                    }
                }
            ]
        },
        plugins: [
            new CleanWebpackPlugin(["dist"]),
            new UglifyJsPlugin({
                parallel     : true,
                sourceMap    : true,
                cache        : true,
                include      : dirname + "/src",
                uglifyOptions: {
                    compress: true,
                    toplevel: true,
                    safari10: true,
                    output  : {
                        comments: false
                    }
                }
            }),
            new webpack.optimize.ModuleConcatenationPlugin(),
            new webpack.SourceMapDevToolPlugin({
                filename  : "sourcemaps/[name].js.map",
                lineToLine: true
            }),
            new BundleAnalyzerPlugin({ analyzerMode: "static" }),
            new CopyWebpackPlugin(
                [
                    {
                        from: dirname + "/src/index.html",
                        to  : dirname + "/dist",
                        transform(htmlAsBuffer) {
                            return Buffer.from(
                                HTMLMinifier.minify(
                                    htmlAsBuffer.toString("utf8"),
                                    {
                                        collapseWhitespace         : true,
                                        collapseBooleanAttributes  : true,
                                        collapseInlineTagWhitespace: true
                                    }
                                )
                            );
                        }
                    }
                ],
                {}
            )
        ],
        performance: {
            hints: "warning"
        }
    };
}

module.exports = buildProductionConfig;

1 个答案:

答案 0 :(得分:0)

似乎我没有发布回购链接(或已将其删除),但今天我设法清除了所有痛点。如果您想查看一个有效的示例,请访问以下网址:https://github.com/ethernal/react-boilerplate

最初的问题是我尝试两次转换TS / JS文件。

PS。如果有人感兴趣,请提供有关配置以及如何进行改进的评论。