时间:2020-10-08 13:28:52 | 栏目:JavaScript代码 | 点击:次
资源
项目目录
├── 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 带来很多好处:
需求
要搭建一个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入口文件
因为大部分项目是多入口,多类别的,所有入口配置时不要配置单一入口
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的到来减少了很多的配置,它内置了很多的功能。相较以前的版本提升了很多,减少了很多专门的配置
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 // 自动打开首页 } }