React笔记三:从0开始搭建项目配置

随着create-react-appcreate-react-native-appvue-clipoi等一系列脚手架的大行其道,让很多入门级的前端工程师往往并不知道 webpack 最基础的原理与配置方法。

这里想用最简单的 webpack4 和 babel7 的最简单的配置方法来说明 react 项目的编译原理等。

怎么编译 JSX

JSX 应该是属于 react 的精髓,模版响应等都表现在此。而面试过很多人,发现他们对 JSX 的解析并不了解。typescript 应该是很多前端工程师的装逼利器,但是他们往往不知道如何在已有的项目中使用 typescript,或者说不知道 jsx 的编译原理。

.vue文件不同,JSX 是在 babel 转译的过程当中完成。在 vue 项目当中,单个.vue文件会被称为 SFC(Single File Component 单文件组件),样式,模版,脚本都会在一个文件内,他们是由vue-loader转换为 js 代码。所以整个编译过程是在 webpack 的独立 loader 完成。

<img src="../image.png" />

会编译为:

createElement("img", {
  attrs: {
    src: require("../image.png"), // this is now a module request
  },
});

而 jsx 的编译是在 babel 内通过babel-preset-react完成,它当中包含了三个独立的 babel 插件。

需要在babel.config.js中配置 preset。

module.exports = {
  presets: ["@babel/preset-react"],
};

或者在 package.json 中配置 babel 对象。

  "babel": {
    "presets": [
      "@babel/preset-react"
    ]
  },

基于 webpack 是的极简配置,webpack.config.js 可以如下配置,详情GITHUB 原码

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].bundle.js",
  },
  devServer: {
    contentBase: path.resolve(__dirname, "dist"),
    port: 9000,
  },
  module: {
    rules: [
      {
        test: /\.js|jsx$/,
        use: "babel-loader",
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      title: "react",
      inject: true,
      template: "./src/index.html", // 模板地址
    }),
  ],
};

怎么把它升级为 tsx 版本

如今我们知道 jsx 的编译是基于@babel/plugin-syntax-jsx的语法树转换。如果想把项目升级到 typescript。丢掉 babel 是不可能的,否则会导致 jsx 转译失败。所以这里需要在 babel 的生态中使用 typescript 的 preset。

现在的人是越来越分不清 es5,es2015,es6,或者是最新的规范。如果在没有 babel 的项目当中,使用 es6 语法会导致低版本浏览器兼容性报错。

babel7 使用 @babel/preset-env 作为最新的 js 语法规范,不需要再去管es2015以及各种stage的问题,可以通过browserslist进行转换。

@babel/preset-typescript 则是可以用于替换掉 @babel/preset-env ,采用 ts 的最新语法规范进行项目开发。package.json 可以改为:

  "babel": {
    "presets": [
      [
        "@babel/preset-typescript",
        {
          "isTSX": true,
          "allExtensions": true
        }
      ],
      "@babel/preset-react"
    ]
  },

其中 isTSX 的选项是用于强制打开 jsx 的解析。否则,var foo = <string>bar将会被 jsx 语法误解,详情 GITHUB 原码

题外话

shopee,又称虾皮,是一家腾讯投资的跨境电商平台。这里加班少,技术氛围好。如果想和我并肩作战一起学习,可以找我内推。邮箱weiping.xiang@shopee.com,非诚勿扰。