review

In the last phase, we built a basic Webpack framework that ADAPTS to normal JS code: here’s how I built the generic Webpack scaffolding for React+TS (Phase 1). However, there are several major problems: no UI framework is loaded; Not used with Typescript; .

So today, move on to phase two, putting React and Typescript into the scaffolding to meet business needs.

The body of the

Tie-in Typescript

Initialize the

First, install dependencies in our project:

yarn add --dev typescript
Copy the code

Then, use the TSC –init command in your project to generate the tsconfig file in the root directory. Here I manually searched for a generic tsconfig template for React:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true
  },
  "exclude": [
    "node_modules",
    "dist"
  ],
  "types": [
    "typePatches"
  ]
}
Copy the code

Next, change all js files in our directory to TS.

An error occurred?

At this point, in ourindex.ts}}}}}}}}}}

According to the hint, the corresponding types specification should be missing. After searching for information, you need to put the declaration file of the corresponding PNG, SVG, JPG file. The following uses the PNG declaration file as an example:

Create a file named import-png.d.ts in the SRC directory with the following contents:

declare module '*.png' {
  const content: any;

  export default content;
}
Copy the code

At the same time, incidentally also add SVG, GIF and other files declaration file, just need to use the above content as a template.

At this point, open our index.ts again and you can see that the red line error has been resolved.

Introducing ts – loader

Since ts is used, there is an extra step when webPack is packaged, which needs to convert TS to JS code first, so we need to introduce TS-Loader to help do this.

// webpack.base.config.js module.exports = { //... Module: {rules: [{test: /. (ts | TSX) $/, / / because after to react, so here write ahead of TSX use: [{loader: 'thread - loader, the options: { } }, 'babel-loader', { loader: 'ts-loader', options: { happyPackMode: true, transpileOnly: true } } ], exclude: /node_modules/, }, //... ]  }, resolve: { extensions: ['.tsx', '.ts', '.js'], }, }Copy the code

Configure the React

After adding the basic ts configuration, let’s start configuring the React dependencies.

Install dependencies:

yarn add react react-dom
yarn add --dev @types/react @types/react-dom
Copy the code

Modify related files

TSX/index.tsx/index.tsx/index.tsx/index.tsx/index.tsx/index.tsx/index.tsx/index.tsx/index.tsx/index.tsx/index.tsx

import React from 'react'; import ReactDOM from 'react-dom'; import Apps from './Apps'; const rootId = 'root'; const rootElement = document.getElementById(rootId); if (! rootElement) { throw new Error(`Unable to find element with id '${rootId}'`); } ReactDOM.render( <Apps />, rootElement );Copy the code

Create Apps. TSX

import React from 'react'; import imageUrl from '.. /public/assets/a.png' const Apps = (): React.ReactElement => { return ( <div> <p>Apps content</p> <img src={imageUrl} alt=""/> </div> ) } export default Apps;Copy the code

Modify the public/index. HTML

<! doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, User - scalable = no, initial - scale = 1.0, the maximum - scale = 1.0, Minimum -scale=1.0"> <meta HTTP-equiv =" x-UA-compatible "content=" IE =edge"> <title>Document</title> </head> <body> <div id="root"></div> <script src="js/test.js"></script> </body> </html>Copy the code

At this point, run the project using YARN Start and you can already see the project displayed in the browser!

The React + typescript collaboration is now working happily.

Babel supports React and lazy loading

Install dependencies

yarn add --dev @babel/plugin-syntax-dynamic-import @babel/preset-react
Copy the code

Open the.babelrc file

{
  "presets": [
    ["@babel/preset-env"],
    ["@babel/preset-react", {"targets": {"node": "current"}}]
  ],
  "plugins": [
    ["@babel/plugin-transform-runtime", {"corejs": 3}],
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }],
    ["@babel/plugin-proposal-private-methods", { "loose": true }],
    ["@babel/plugin-syntax-dynamic-import"]
  ]
}
Copy the code

Installing tailwindcss (optional)

Due to the requirements of the company’s technology stack, there is a need to continue to configure tailwindcss

Install dependencies:

yarn add --dev tailwindcss@latest @fullhuman/postcss-purgecss cssnano
Copy the code

Here we use postCSS in combination with tailwindCSS, creating the postcss.config.js file in the root directory

//postcss.config.js

const tailwindcss = require("tailwindcss");
const purgecss = require("@fullhuman/postcss-purgecss");


class TailwindExtractor {
  static extract(content) {
    return content.match(/[A-z0-9-:/]+/g);
  }
}

module.exports = {
  plugins: [
    tailwindcss("./tailwind.config.js"),
    require("autoprefixer"),
    require("cssnano")({ preset: "default" }),
    process.env.NODE_ENV === "production" &&
    purgecss({
      content: ["**/*.html", "./src/**/*.ts",  "./src/*.ts", "./src/*.tsx", "./src/**/*.tsx"],
      css: ["./src/**/*.css"],
      extractors: [
        {
          extractor: new TailwindExtractor,
          // Specify the file extensions to include when scanning
          extensions: ["html", "ts", "tsx", "css"]
        }
      ]
    })
  ]
};
Copy the code

Create a taiwindcss.config.js file in the root directory using the NPX tailwindCSS init command according to the official tailwindCSS documentation

//taiwindcss.config.js
module.exports = {
  purge:  {
    enabled: true,
    content: [
      './public/*.html',
      './src/*.tsx',
      './src/**/*.tsx'
    ],
  },
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
Copy the code

Then, you need to create a CSS folder in the SRC directory that contains the styles. CSS and output.css files. Output.css is a packaged style file.

//styles.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Copy the code

Then, for the generated style to work, it needs to be introduced in the index.tsx file

import './css/output.css'

//...
Copy the code

Next, you need to configure the project’s packaging commands, which use postCSS-CLI and the CONCURRENTLY tool

yarn add --dev postcss-cli concurrently
Copy the code

Reconfigure our scripts command

{... "scripts": { "start": "webpack serve --config build/webpack.dev.config.js --open", "dev": "concurrently \"yarn watch:css \" \"yarn start \"", "build": "yarn build:css && yarn build:prod", "build:prod": "npx webpack --config build/webpack.prod.config.js", "build:css": "postcss src/css/styles.css -o src/css/output.css", "watch:css": "postcss src/css/styles.css -o src/css/output.css -w", } }Copy the code

In a development environment, it is best to use the yarn dev command for development, which supports hot code replacement and hot update of tailwindcss. Formal packaging is performed using the YARN build command.

Code Analysis Report (optional)

Use the Webpack-bundle-Analyzer plug-in to generate code analysis reports to help improve code quality and site performance.

Install dependencies:

yarn add -dev webpack-bundle-analyzer
Copy the code

Related configurations:

//webpack.dev.config.js
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");

module.exports = merge(baseConfig, {
    //...
    plugins: [
      ...baseConfig.plugins,
      new BundleAnalyzerPlugin()
    ],
})
Copy the code

conclusion

React, Typescript, and Taiwindcss support for a generic Webpack scaffolding that can be used by common projects. Source link: github.com/wbh13285517… .