Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从0搭建react-ts开发环境 #18

Open
liucaieson opened this issue May 3, 2021 · 0 comments
Open

从0搭建react-ts开发环境 #18

liucaieson opened this issue May 3, 2021 · 0 comments

Comments

@liucaieson
Copy link
Owner

liucaieson commented May 3, 2021

新建文件夹

生成一个package.json文件

mkdir react-ts
cd react-ts
npm init -y

初始化ts配置

npm install --save-dev typescript ts-loader
新建rsconfig.json文件 添加配置

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",  // 制定生成什么模块的代码
    "moduleResolution": "node",
    "importHelpers": true,
    "jsx": "react-jsx",
    "esModuleInterop": true,
    "sourceMap": true,
    "baseUrl": "./",
    "strict": true,
    "allowSyntheticDefaultImports": true
  },
  "include": [
    "mock/**/*",
    "src/**/*",
    "config/**/*",
    "typings.d.ts"
  ],
  "exclude": [
    "node_modules",
    "lib",
    "es",
    "dist",
    "typings",
    "**/__test__",
    "test",
    "docs",
    "tests"
  ]
}

配置webpack

npm i webpack webpack-cli webpack-merge html-webpack-plugin clean-webpack-plugin --dev
新建config文件存放webpack配置文件
webpack.config.common.js 存放webpack的公共配置
webpack.config.dev.js 存放webpack的开发环境配置
webpack.config.prod.js 存放webpack的生产环境配置
cleanWebpackPlugin 清除打包文件
HtmlWebpackPlugin 生成HTML5文件

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
 // 一个单页应用需要配置一个entry入口,
  entry: {
    app: './src/index.tsx',
  },
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[hash].js',
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'REACT-TS',
      template: path.resolve(__dirname, '../index.html'),
      filename: 'index.html',
    }),
    new CleanWebpackPlugin(),
  ],
}

###通过webpack-merge 合并配置项
// config/webpack.config.dev.js
生成环境同理

const webpackMerge = require('webpack-merge')
const baseConfig = require('./webpack.config.common')

const devConfig = {
  mode: 'development',
}

module.exports = webpackMerge(baseConfig, devConfig)

安装开发服务器

npm i webpack-dev-server --dev
配置端口

devServer: {
    port: 3001,
    hot: true,
    contentBase: "./dist",
  }

配置启动命令

scripts:{
    "serve": "webpack server --config webpack.config.js --open"
   }

如果你装了webpack-dev-server 而配置了 webpack-dev-server --config webpack.config.dev.js --open
会出现版本不匹配的报错
image
原因在这里 webpack/webpack-dev-server#2759

配置babel

安装依赖
npm i babel-loader babel-plugin-import @babel/cli @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript --dev
按照官网配置
在根目录新建.babelrc文件

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

webpack.config.common.js中添配置

module: {
    rules: [
      { test: /\.(js|jsx)$/, loader: 'babel-loader', exclude: /node_modules/ },
      { test: /\.(ts|tsx)$/, loader: 'ts-loader', exclude: /node_modules/ },
    ],
  },

配置React

npm i react react-dom react-router-dom
npm i @types/react @types/react-dom @types/react-router-dom --dev

新建src目录 创建App.tsx ,index.tsx文件

解析样式

npm i style-loader sass-loader sass css-loader postcss-loader postcss-normalize autoprefixer postcss-preset-env -D
增加配置
postcss-loader作用
把css解析为一个抽象语法树
调用插件处理抽象语法树并添加功能
所以他要放到css-loader的下面。scss-loader的上面,用来处理scss-loader生成的文件。
结合 autoprefixer(添加浏览器前缀) postcssNormalize(帮你加入Normalize.css)
新增postcss.config.js文件并配置

const postcssNormalize = require('postcss-normalize')

module.exports = {
  plugins: [
    [
      'postcss-preset-env',
      {
        autoprefixer: {
          flexbox: 'no-2009',
        },
        stage: 3,
      },
    ],
    postcssNormalize(),
    require('autoprefixer')({
      overrideBrowserslist: ['last 2 version', '>1%', 'ios 8'],
    }),
  ],
}

webpack.config.dev.js

 {
        test: /\.(css|scss)$/,
        exclude: /\.module\.scss$/,
        use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
      }

图片解析

webpack5 内置 assets 类型,我们不需要额外安装插件就可以进行图片等资源文件的解析,配置如下:

{
  test: /\.(jpe?g|png|gif|svg|woff|woff2|eot|ttf|otf)$/i,
  type: "asset/resource",
},

性能优化

webpack5 引入了缓存来提高二次构建速度,我们只需要在 webpack 配置文件中加入如下代码

cache: {
  type: 'filesystem',
  // 可选配置
  buildDependencies: {
    config: [__filename], // 当构建依赖的config文件(通过 require 依赖)内容发生变化时,缓存失效
  },
  name: 'development-cache',
}

提取css

上面的css是打入到js中的,我们需要把css单独打出来
npm install --save-dev mini-css-extract-plugin

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
	...
  plugins: [new MiniCssExtractPlugin({
              filename: 'css/[name].[hash].css',
	})],
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
}

MiniCssExtractPlugin vs style-loader

这里介绍一下他两的不同
两个插件用途不同:MiniCssExtractPlugin 提取 JS 中引入的 CSS 打包到单独文件中,然后通过标签 添加到头部
style-loader 把js中import导入的样式文件打包到js文件中,运行js文件时,将样式自动插入到<style>标签中。
两种方式各有优劣。

添加build

"build": "webpack --mode=production --config ./config/webpack.config.prod.js"

开启source-map

devtool: 'inline-source-map',

eval

  • 通过eval包裹每一个module模块,编译后不会生成sourcemap文件,仅仅是在每一个模块后,增加sourceURL来关联模块处理 * 前后对应的关系
  • 优点是:打包速度非常快,因为不需要生成sourcemap文件。
  • 缺点是:由于会映射到转换后的代码,而不是映射到原始代码,所以不能正确的显示行数。

source-map

  • 为每一个打包后的模块生成独立的sourcemap文件,打包后的代码最后面一句代码是 // #sourceMappingURL=bundle.js.map ,同时在dist目录下会针对每一个模块生成响应的 .map文件
  • 拥有完整的源代码信息,便于调试,但影响持续构建

inline

  • 不会生成独立的 .map文件,而是将.map文件以dataURL的形式插入
  • 缺点:打包输出文件变大

cheap

  • 打包后同样会为每一个文件模块生成 .map文件,但是与source-map的区别在于cheap-source-map生成的 map文件会忽略原始代码中的列信息
  • 可以大幅提高souremap生成的效率,但没有列信息(会映射到转换后的代码,而不是映射到原始代码),通常我们调试并不关心列信息

module

  • 同样生成一个没有列的信息的sourcemap文件,同时loader的sourcemap也被简化成为只包含对应行
  • 支持babel这种预编译工具,找到最初源码信息

如何根据不同环境选择相应sourceMap 生成策略?

  • 源代码中的列信息是没有任何作用,因此我们打包后的文件不希望包含列相关信息,只有行信息能建立打包前后的依赖关系。因此不管是开发环境或生产环境,我们都希望添加cheap的基本类型来忽略打包前后的列信息。

  • 不管是开发环境还是正式环境,我们都希望能定位到bug的源代码具体的位置,比如说某个vue文件报错了,我们希望能定位到具体的vue文件,因此我们也需要module配置。

  • 我们需要生成map文件的形式,因此我们需要增加source-map属性。

知道eval打包后的速度非常快,因为它不生成map文件,但是可以对eval组合使用eval-source-map使用会将map文件以DataURL的形式存在打包后的js文件中

// 在开发环境中我们可以使用 , eval加快打包效率
module.exports = {
  devtool: 'cheap-module-eval-source-map'
}

// 在正式环境中我们可以使用  
module.exports = { 
  devtool: 'cheap-module-source-map';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant