React+TypeScript+webpack4多入口配置详解


Posted in Javascript onAugust 08, 2019

资源

  • React-16.8.*
  • react-router-dom-4.3.*
  • TypeScript-3.5.*
  • webpack-4.*
  • eslint-5.16.*

项目目录

├── dist # 打包结果目录
│  ├── demo1 //类别demo1的打包结果
│  │  ├── demo1.himl
│  │  ├── demo1.js
│  │  └── demo1.css
│  └── demo2 ... //类别demo2的打包结果
├── src # 业务资源文件目录
│  ├── category //项目分类
│  │  ├── demo1
│  │  ├── demo2
│  │  └── ...
│  ├── components //公共组件
│  ├── util //公共资源
│  └── custom.d.ts //项目全局变量声明文件
├── index.html //项目启动入口
├── .gitignore //git忽略文件
├── .eslintrc.js //eslint校验配置
├── package.json //依赖包
├── tsconfig.json //ts配置
├── webpack.config.build.js //webpack打包
├── webpack.config.base.js //webpack基础配置
└── webpack.config.js //项目启动配置

前言

对于复杂或多人开发的 React 项目来说,管理和使用每个组件的 props 、 state 或许会成为一件让人头痛的事情,而为每一个组件写文档,成本也会比较大,对项目的开发效率也不是最理想的。

Typescript 给 React 带来很多好处:

  • 在组件头部定义 interface,让每个人在拿到组件的第一时间就可以很明确知道该组件需要使用的 props 和 state;
  • 在编译中发现问题,减少运行时的报错;
  • 可以在编辑器中实现实时类型校验、引用查询;
  • 约束类型,在混合多语言环境中降低风险,等。

需求

要搭建一个React+TypeScript+webpack的项目的话,一般都是团队开发多人多文件项目,在搭建之前需要优先考虑以下几个方面:

  • 开发体验
  • 项目打包
  • 团队规范

安装

前置安装

首先需要全局安装typescript,这里默认大家都已经安装了node以及npm

npm install -g typescript

首先新建文件夹并进入

mkdir tsDemo && cd tsDemo

然后进行初始化,生成package.json和tsconfig.json

npm init -y && tsc --init

安装开发工具

npm install-D webpack webpack-cli webpack-dev-server

安装react相关

因为需要整合ts,而react原本的包是不包含验证包的,所以这里也需要安装相关ts验证包

npm install -S react react-dom
npm install -D @types/react @types/react-dom

安装ts-loader

npm install -D ts-loader

以上是基本的 后续会贴出项目demo里面包含所有依赖包

webpack配置

添加webpack文件

根目录下新建webpack.config.base.js、webpack.config.build.js、webpack.config.js文件

touch webpack.config.base.js webpack.config.build.js webpack.config.js
  • entry:入口文件(你要打包,就告诉我打包哪些)
  • output:出口文件(我打包完了,给你放到哪里)
  • resolve: 寻找模块所对应的文件
  • module:模块(放lorder,编译浏览器不认识的东西)
  • plugins:插件(辅助开发,提高开发效率)
  • externals:打包忽略
  • devServer:服务器(webpack提供的本地服务器)
  • mode:模式,分为开发模式、生产模式。此为4.X里新增的

配置entry入口文件

因为大部分项目是多入口,多类别的,所有入口配置时不要配置单一入口

const fs = require("fs");
const path = require("path");
const optimist = require("optimist");

const cateName = optimist.argv.cate;
let entryObj = {};
const srcPath = `${__dirname}/src`;
//获取当前项目要启动或者打包的基础路径
const entryPath = `${srcPath}/category/`;
//未指定类别 启动或者打包所有类别
//如:npm run dev 或者npm run build
if (cateName == true) {
  fs.readdirSync(entryPath).forEach((cateName, index) => {
    // cateName/cateName指定输出路径为entryname
    if (cateName != "index.html" && cateName != ".DS_Store") entryObj[`${cateName}/${cateName}`] = `${entryPath + cateName}/${cateName}.tsx`;
  });
} else if (cateName.indexOf(",")) {
  // 一次指定多个类别 类别之间以","分割
  //如:npm run dev erhsouche,huoche 
  let cateNameArray = cateName.split(",");
  for (let i = 0; i < cateNameArray.length; i++) {
    entryObj[`${cateNameArray[i]}/${cateNameArray[i]}`] = `${entryPath + cateNameArray[i]}/${
      cateNameArray[i]
    }.tsx`;
  }
} else {
  // 打包单个入口文件
  //如:npm run dev ershouche
  entryObj[`${cateName}/${cateName}`] = `${entryPath + cateName}/${cateName}.tsx`;
}
const webpackConfig = {
  entry: entryObj,
}
module.exports = {
  webpackConfig,
  entryObj
};

配置output出口文件

const webpackConfig = {
  output: {
    //输出文件名称以当前传入的cate类别名称命名
    filename: "[name].js", 
    //输出到根目录下的dist目录中
    path: path.resolve(__dirname, "dist"),
    publicPath: "/",
  },
}

配置resolve

需要import xxx from 'xxx'这样的文件的话需要在webpack中的resolve项中配置extensions,这样以后引入文件就不需要带扩展名

const webpackConfig = {
  resolve: {
    extensions: [".tsx", ".ts", ".js", ".jsx", ".json"],
    //配置项通过别名来把原导入路径映射成一个新的导入路径。
    alias: {
      images: path.join(__dirname, "src/util/img")
    },
    // 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
    modules: [path.resolve(__dirname, "node_modules")] 
  },
}

配置module

概念

在webpack中任何一个东西都称为模块,js就不用说了。一个css文件,一张图片、一个less文件都是一个模块,都能用导入模块的语法(commonjs的require,ES6的import)导入进来。webpack自身只能读懂js类型的文件,其它的都不认识。但是webpack却能编译打包其它类型的文件,像ES6、JSX、less、typeScript等,甚至css、images也是Ok的,而想要编译打包这些文件就需要借助loader

loader就像是一个翻译员,浏览器不是不认识这些东西么?那好交给loader来办,它能把这些东西都翻译成浏览器认识的语言。loader描述了webpack如何处理非js模块,而这些模块想要打包loader必不可少,所以它在webpack里显得异常重要。loader跟插件一样都是模块,想要用它需要先安装它,使用的时候把它放在module.rules参数里,rules翻译过来的意思就是规则,所以也可以认为loader就是一个用来处理不同文件的规则

所需loader

ts-loader

编译TypeScript文件

npm install ts-loader -D

url-loader

处理css中的图片资源时,我们常用的两种loader是file-loader或者url-loader,两者的主要差异在于。url-loader可以设置图片大小限制,当图片超过限制时,其表现行为等同于file-loader,而当图片不超过限制时,则会将图片以base64的形式打包进css文件,以减少请求次数。

npm install url-loader -D

css处理所需loader
css-loader 处理css
sass-loader 编译处理scss
sass-resources-loader 全局注册变量

html-loader
处理.html文件

module完整配置

const webpackConfig = {
  module: {
    rules: [
      //处理tsx文件
      { test: /\.(tsx|ts)?$/, use: ["ts-loader"], include: path.resolve(__dirname, "src") },
      //处理图片资源
      {
        test: /\.(png|jpe?g|jpg|gif|woff|eot|ttf|svg)/,
        use: [
          // 对非文本文件采用file-loader加载
          {
            loader: "url-loader",
            options: {
              limit: 1024 * 30, // 30KB以下的文件
              name: "images/[name].[hash:8].[ext]",
            }
          }
        ],
      },
      //处理css和scss
      {
        test: /\.(css|scss)$/,
        use: [
          //css单独打包
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader"
          },
          {
            loader: "postcss-loader",
            options: {
              plugins: () => [require("autoprefixer")],
              sourceMap: true
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          },
          {
            loader: "sass-resources-loader",
            options: {
              resources: ["./skin/mixin.scss", "./skin/base.scss"]
            }
          }
        ],
        exclude: path.resolve(__dirname, "node_modules")
      },
      {
        test: /\.html$/,
        use: {
          loader: "html-loader",
        }
      },
      { test: /src\/containers(\/.*).(tsx|ts)/, loader: "bundle-loader?lazy!ts-loader" },
      { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
    ]
  },
}

配置plugins

plugins里面放的是插件,插件的作用在于提高开发效率,能够解放双手,让我们去做更多有意义的事情。一些很low的事就统统交给插件去完成。

const webpackConfig = {
  plugins: [
    //清除文件
    new CleanWebpackPlugin(),
    //css单独打包
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[name].css"
    }),
    // 引入热更新插件
    new webpack.HotModuleReplacementPlugin() 
  ]
}

配置externals

如果需要引用一个库,但是又不想让webpack打包(减少打包的时间),并且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用(一般都以import方式引用使用),那就可以通过配置externals。

const webpackConfig = {
  //项目编译打包是忽略这些依赖包
  externals: {
    react: "React",
    "react-dom": "ReactDOM",
    "react-redux": "ReactRedux",
  }
}

配置mode

mode是webpack4新增的一条属性,它的意思为当前开发的环境。mode的到来减少了很多的配置,它内置了很多的功能。相较以前的版本提升了很多,减少了很多专门的配置

  • 提升了构建速度
  • 默认为开发环境,不需要专门配置
  • 提供压缩功能,不需要借助插件
  • 提供SouceMap,不需要专门配置

mode分为两种环境,一种是开发环境(development),一种是生产环境(production)。开发环境就是我们写代码的环境,生产环境就是代码放到线上的环境。这两种环境的最直观区别就是,开发环境的代码不提供压缩,生产环境的代码提供压缩。

配置devServer

const webpackConfig = {
  devServer: {
    // 本地服务器所加载的页面所在的目录
    contentBase: srcPath, 
    //热更新
    hot: true,
    //服务端口
    port: "7788",
    // 是否向Chunk中注入代理客户端,默认注入
    inline: true, 
    // publicPath: '/dist/',
    historyApiFallback: {
      index: "template.html",
    },
    //默认检查hostname
    disableHostCheck: true,
    compress: true,
    open: true // 自动打开首页
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript confirm选择判断
Oct 18 Javascript
用于判断用户注册时,密码强度的JS代码
Jan 01 Javascript
jquery.pagination.js 无刷新分页实现步骤分享
May 23 Javascript
一个封装js代码-----展开收起效果示例
Jul 03 Javascript
js实现鼠标经过时图片滚动停止的方法
Feb 16 Javascript
jQuery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较
Jul 14 Javascript
js Canvas绘制圆形时钟教程
Feb 06 Javascript
利用node.js搭建简单web服务器的方法教程
Feb 20 Javascript
nginx配置React静态页面的方法教程
Nov 03 Javascript
vue获取当前激活路由的方法
Mar 17 Javascript
jQuery pjax 应用简单示例
Sep 20 jQuery
jQuery+ajax实现文件上传功能
Dec 22 jQuery
JavaScript:ES2019 的新特性(译)
Aug 08 #Javascript
thinkjs微信中控之微信鉴权登陆的实现代码
Aug 08 #Javascript
Vue指令之 v-cloak、v-text、v-html实例详解
Aug 08 #Javascript
javascript实现blob加密视频源地址的方法
Aug 08 #Javascript
使用ThinkJs搭建微信中控服务的实现方法
Aug 08 #Javascript
微信小程序云函数使用mysql数据库过程详解
Aug 07 #Javascript
js如何实现元素曝光上报
Aug 07 #Javascript
You might like
Laravel如何实现适合Api的异常处理响应格式
2020/06/14 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
js算法中的排序、数组去重详细概述
2013/10/14 Javascript
js菜单点击显示或隐藏效果的简单实例
2014/01/13 Javascript
javascript发送短信验证码实现代码
2015/11/12 Javascript
jquery实现select选择框内容左右移动代码分享
2015/11/21 Javascript
bootstrap模态框消失问题的解决方法
2016/12/02 Javascript
使用ionic(选项卡栏tab) icon(图标) ionic上拉菜单(ActionSheet) 实现通讯录界面切换实例代码
2017/10/20 Javascript
使用jQuery 操作table 完成单元格合并的实例
2017/12/27 jQuery
Django+Vue跨域环境配置详解
2018/07/06 Javascript
JavaScript闭包原理与用法实例分析
2018/08/10 Javascript
中高级前端必须了解的JS中的内存管理(推荐)
2019/07/04 Javascript
JS sort排序详细使用方法示例解析
2020/09/27 Javascript
[01:04:01]2014 DOTA2华西杯精英邀请赛5 24 DK VS VG
2014/05/25 DOTA
Python实现HTTP协议下的文件下载方法总结
2016/04/20 Python
python 信息同时输出到控制台与文件的实例讲解
2018/05/11 Python
pycharm 解除默认unittest模式的方法
2018/11/30 Python
python图的深度优先和广度优先算法实例分析
2019/10/26 Python
python利用文件时间批量重命名照片和视频
2021/02/09 Python
html5在移动端的屏幕适应问题示例探讨
2014/06/15 HTML / CSS
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
HomeAway澳大利亚:预订你的度假屋,公寓、度假村、别墅等
2019/02/20 全球购物
法学专业毕业生自荐信范文
2013/12/18 职场文书
人事文员岗位职责
2014/02/16 职场文书
小学班主任评语大全
2014/04/23 职场文书
责任胜于能力演讲稿
2014/05/20 职场文书
奉献演讲稿范文
2014/05/21 职场文书
读群众路线的心得体会
2014/09/03 职场文书
党支部创先争优公开承诺书
2015/04/30 职场文书
预备党员群众意见
2015/06/01 职场文书
运动会开幕式致辞
2015/07/29 职场文书
烈士陵园扫墓感想
2015/08/07 职场文书
PhpSpreadsheet中文文档 | Spreadsheet操作教程实例
2021/04/01 PHP
python numpy中setdiff1d的用法说明
2021/04/22 Python
Go语言切片前或中间插入项与内置copy()函数详解
2021/04/27 Golang
「天才王子的赤字国家重生术」妮妮姆·拉雷粘土人开订
2022/03/21 日漫