create-react-app
- react中文论坛: http://react-china.org/
环境
- 创建react webpack环境
- ts版本
create-react-app keshihua --scripts-version=react-scripts-ts
- jsx版本
create-react-app keshihua
- 暴露配置项
npm run eject
- 增加对less的支持
npm install less-loader less --save-dev
- 修改
webpack.config.dev.js
和webpack.config-prod.js
配置文件
-
/\.css$/
改为/\.(css|less)$/
- 关键字
exclude
增加或修改/\.(css|less)$/
- 在修改
/\.(css|less)$/
的代码中, use数组中加入{loader: require.resolve('less-loader')}
主要修改文件
config/webpack.config.dev.js
config/webpack.config.prod.js
config/paths.js
- 设置paths
在config/paths.js
抛出的参数中需要设置以下2个参数
-
appBuild
: 编译的目录 -
appSrc
: 源文件的目录
- 设置
module.exports.output
-
filename
作为js的目标文件夹,publicPath
是编译根目录
如:publicPath
设置为/bulid/
,filename
设置为js/[name].js
, 则最后生成的js位置是/build/js/[name].js
-
entry
作为需要编译的js文件, 这里的路径是相对于项目根目录的, 最好写绝对路径 -
HtmlWebpackPlugin 用来编译html,
template
属性作为需要编译的html, 路径相对于项目根目录, 最好写绝对路径 -
cssFilename
属性作为编译css的目录 -
oneOf
中寻找代码static/media/[name].[hash:8].[ext]
, 这个是资源路径
- 代码书写风格
使用create-react-app 编译后的代码支持ES6, less, npm包管理
引入一个文件通常使用import
引入, 如
import React, { Component } from 'react';
// or
import * as React from 'react';
// or
import 'antd/lib/affix/style';
less也可以通过import引入, 如
import './mobileBox.less';
抛出一个方法使用 export
export default MobileBox;
// or
export {MobileBox};
-
JSX语法
使用react支持JSX语法, 可以直接使用<div></div>的形式传值 -
一个文本闪烁的 demo
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
class A extends Component {
constructor() {
super();
this.state = {
display: 'block'
}
}
componentDidMount() {
setInterval(() => {
this.setState({
display: this.state.display === 'block' ? 'none': 'block'
});
}, 1000);
}
render () {
return <div style={{
display: this.state.display
}}>hello world</div>
}
}
ReactDOM.render(<A />, document.body);
- 如何使用create-react-app 来编译多页面项目
6.1. 全局搜索checkRequiredFiles
, 清除对appBuild
,appSrc
的检查(找到以下代码并删除或注释)if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { process.exit(1); }
6.2 增加node代码如下:
let HtmlWebpackPlugins = [];
let entry = {};
let htmlIndexArr = [];
/**
* readdirsSync 深度寻找一个路径下的所有文件
* @param pathName 路径
* @param callback 回调函数
*
* 其他参数不用管, 回调使用
* 回调中存在可以使用 srcFileName, fileName, middlePath
* srcFileName: 文件路径
* fileName: 文件名
* middlePath: 相对pathName路径
* 如传入的pathName为 a/, 实际路径为 a/b/c.js 则middlePath的值为b/c.js
*
* 使用call, apply 调用的时候, 可以为this传入一个数字, 作为最大递归层数
*/
function readdirsSync(pathName, callback, middle = pathName, z = 0) {
let numberThis = Number(this);
if (numberThis && z >= numberThis) return;
fs.readdirSync(pathName).forEach((fileName) => {
let srcFileName = path.join(pathName, fileName);
let stat = fs.statSync(srcFileName);
if (stat && stat.isFile()) {
let middlePath = pathName.replace(middle, '');
callback({ srcFileName, fileName, middlePath });
} else if (stat && stat.isDirectory()) {
readdirsSync.call(this, srcFileName, callback, pathName, z + 1);
}
});
}
/**
* getChunks 获取一个文件的标识, 每个文件的标识是唯一的
* @param pathName
* @param middle
*/
function getChunks(pathName, middle) {
let str = path.join(middle, pathName.split('.').slice(0, -1).join('.')).replace(/\\/g, '/');
str.startsWith('/') && (str = str.replace('/', ''));
return str;
}
// 主页面名必须是index
readdirsSync.call(2, paths.appSrc, function ({ srcFileName, fileName, middlePath }) {
// 判断文件是否是js文件
if (/^index.(js|jsx|ts|tsx)$/.test(fileName)) {
// 获取文件唯一标识
let chunkName = getChunks(fileName, middlePath);
// 去除路径中的/
let seps = middlePath.replace(path.sep, '');
// 如果路径的目录是public,shared,images,data则跳过, 这些路径是预设的非组件的路径
if (['public', 'shared', 'images', 'data'].indexOf(seps) !== -1) return;
// 设置编译文件
entry[chunkName] = [srcFileName];
// 获取html模板文件路径
let templateUrl = srcFileName.split('.').slice(0, -1).join('.') + '.html';
// 是否存在这个模板, 如果不存在的话会用默认的模板代替
let tempStat = fs.existsSync(templateUrl);
// 设置html编译
var htmlWebpackPlugin = new HtmlWebpackPlugin({
inject: true,
template: tempStat ? templateUrl : path.join(__dirname, 'webpack.html'),
hash: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
chunks: [chunkName],
filename: path.join(paths.appBuild, '/html/', middlePath + '.html')
})
htmlIndexArr.push(path.join('/build/html/', middlePath + '.html'));
HtmlWebpackPlugins.push(htmlWebpackPlugin);
}
});
网友评论