GithubHelp home page GithubHelp logo

freyhill / react-multi-page-app Goto Github PK

View Code? Open in Web Editor NEW
236.0 12.0 85.0 478 KB

🍡 react multi page app/react多页面应用

Home Page: https://h5cool.com/react-multi-page-app/demo

License: MIT License

JavaScript 89.47% HTML 2.57% SCSS 7.96%
webpack4 react16 es6 multiple scaffold multi-page node react reactjs webpack

react-multi-page-app's Introduction


       

react-multi-page-app


English | 中文

React-multi-page-app is a multi-page application architecture based on react and webpack. Through compiling and generating static pages with clear corresponding directory structure, multi-page development and maintenance can be realized conveniently.

Overview

key value
name react-multi-page-app
desc a scaffold of create react multi page app
cli rppx
author leinov
version 1.3.0

Feature

  • 👩‍👩‍👧‍👧 Support multiple pages simultaneously hot loading development
  • 📇 Automatically identifies newly created pages
  • 📝 Each page generates personalized information
  • 🚻 Classification of packaging
  • 🔗 Flexible extend

Install

npm install rppx-cli -g

Quick Start

install rppx-cli in global and create your new project ,use npm start the project

install

$ npm install rppx-cli -g

create your multi page

$ rppx init my-react

install dependencies

$ npm install 

dev

$ npm run dev

build

$ npm run build

start project

$ npm start

Automatically open browser with development: http://localhost:3100 / production: http://localhost:3118

Usage

create a new page in the pages directory of src. and run npm run dev in the root directory of project

|-- src
    |-- index/
    |-- page2/
        |-- index.js
        |-- page2.scss
        |-- pageinfo.json
  • How to implement
  • How to structure
  • Use in detail

Version

version desc
1.3.0 add cli
add demo page
refactoring and optimize
1.2.0 add html template
1.1.0 init

License

MIT

react-multi-page-app's People

Contributors

freyhill avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-multi-page-app's Issues

react-multi-page-app wiki

react多页面应用架构及使用

概览

key value
名称 react-multi-page-app
描述 react多页面应用教授教
开发者 leinov
版本 1.3.0
仓库 github地址

特性

  • 👩‍👩‍👧‍👧 支持多页面同时热加载开发
  • 📇 自动识别新创建页面
  • 📝 每个页面生成个性化信息
  • 🚻 分类打包
  • 🔗 灵活扩展

安装&使用

// install cli

$ npm install rppx-cli -g

// 创建项目
$ rppx init my-react

// 安装依赖包
$ npm install 

// 开发
$ npm run dev

// 编译打包
npm run build

// 启动生产页面
npm start

新创建页面在src下添加文件夹并创建pageinfo.json 然后npm run dev 即可

|-- src
    |-- index/
    |-- page2/
        |-- index.js
        |-- pageinfo.json

技术使用

  • react16
  • webpack4
    • html-webpack-plugin 生成html文件
    • mini-css-extract-plugin css分离打包
    • uglifyjs-webpack-plugin js压缩
    • optimize-css-assets-webpack-plugin css压缩
  • es6
  • babel
  • sass&bulma
  • react-redux
  • node
    • opn 打开浏览器
    • compression 开启gzip压缩
    • express
    • fs&progress
  • git

目录结构

|-- react-multi-page-app //项目
    |-- build //编译生产目录
        |-- index
            |-- index.css
            |-- index.js
        |-- todo
            |-- todo.css
            |-- todo.js
            |-- index.html
        |-- images
        |-- index.html
    |-- node_modules //node包
    |-- src //开发目录
        |-- pages
            |-- index
                |-- index.js // 页面打包入口文件(必须)
            |-- todo
        |-- utils.js
        |-- common.scss
        |-- template.html // html模版
    |-- config //在webpack中使用
        |-- get-entry.js //获取入口
        |-- get-path.js //src下需要打包页面文件夹
        |-- html-config.js //每个页面html注入数据
    |-- package.json
    |-- .gitignore
    |-- webpack.config.js //webpack配置文件
    |-- www.js //生产启动程序

实现

webpack打包单页面应用

webpack在单页面打包上应用广泛,以create-react-app为首的接触脚手架众多,单页面打包通常指的是将业务js,css打包到同一个html文件中,整个项目只有一个html文件入口

webpack单页面打包配置

webpack.config.js

module.exports = (env, argv) => ({
	entry: ".src/index.js",
	output: {
		path: path.join(__dirname, "dist"),
		filename: "bundle.js"
	},
	module: {
		rules: [
		...
		],
	},
	plugins: [
	    new HtmlWebpackPlugin({
    		title: "首页",
    		filename:"index.html",
    		favicon:"",
    		template: "./src/template.html",

	    })
	]
});

这样就可以在dist文件夹下打包出一个下面这样的文件

<!DOCTYPE html>
<html lang="en">
    <head>
    <title>首页</title>
    <body>
        <div id="root"></div>
        <script type="text/javascript" src="bundle.js"></script></body>
</html>

webpack多页面打包配置

webpack 的entry支持两种种格式

打包单个文件

module.exports = {
  entry: '.src/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
};

这样就会在dist下打包出一个bundle.js

打包出多个文件

module.exports = {
  entry: {
    index:"./src/index.js",
    about:"./src/about.js"
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js' index.js,about.js这两个文件
  }
};

上面在dist下打包出两个与entry属性名对应的js文件

将每个js挂载到相应的html文件上

这里我们需要用到html-webpack-plugin这个webpack插件,每添加一个页面就需要在plugins添加一个new HtmlWebpackPlugin({....})

const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = (env, argv) => ({
    entry: {
        index:"./src/index.js",
        about:"./src/about.js"
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js' index.js,about.js这两个文件
    }
    ....//其他配置
    plugins: [
        new HtmlWebpackPlugin(
            {
        		filename:"index.html",//生成的index.html
        		template: "./src/template.html",}) //模板
        		chunks:["index"]
            }),
		new HtmlWebpackPlugin(
		    {
        		filename:"about.html",//生成的index.html
        		template: "./src/template.html",}) //模板
        		chunks:["index"]
        	})
	]
})

html-webpack-plugin 会通过 template.html 模板生成对应的filename名的html文件,并一并打包到output中对应的文件夹下,注意,在没有特殊配置的情况下所有打包的文件都是对应到output中 path 这个目录下,也包括html。这里的 chunks 需要注意,它是确定该html需要引入哪个js,如果没写的话,默认会引出所有打包的js,当然这不是我们想要的。

上面的配置最终可以在dist下打包出下面的文件结构

|-- dist
    |-- index.js
    |-- about.js
    |-- index.html //内挂载index.js
    |-- about.html //内挂载about.js

通过上面这样的配置,再加上devServer,我们已经可以实现多页面的配置开发了,但这样很不智能,因为你每增加一个页面,就要在wepback里面配置一次,会非常繁琐,所以我们来优化下,让我们只专注于开发页面,配置交给webpack自己.

webpack多页面配置优化

我们再看下src下面的文件结构

|-- src
    |-- index
        |-- app.js
        |-- index.scss
        |-- index.js
    |-- about
        |-- app.js
        |-- index.scss
        |-- index.js

src下面每个文件夹对应一个html页面的js业务,如果我们直接把文件夹对应入口js找到并把他们合并生成对应的entry,那是不是就不用手动写entry了呢,是的!

遍历文件目录

/* eslint-env node */

/**
 * @project: 遍历文件目录
 * @author: leinov
 * @date: 2018-10-11
 */

const fs = require("fs");

/**
 * 【遍历某文件下的文件目录】
 *
 * @param {String} path 路径
 * @returns {Array} ["about","index"]
 */
module.exports = function getPath(path){
	let arr = [];
	let existpath = fs.existsSync(path); //是否存在目录
	if(existpath){
		let readdirSync = fs.readdirSync(path);  //获取目录下所有文件
		readdirSync.map((item)=>{
			let currentPath = path + "/" + item;
			let isDirector = fs.statSync(currentPath).isDirectory(); //判断是不是一个文件夹
			if(isDirector){ // component目录下为组件 需要排除
				arr.push(item);
			}
		});
		return arr;
	}
};
};

比如在src下有index页面项目,about项目 遍历结果为["index","about"];

遍历生成打包入口数组

/* eslint-env node */
/**
 * @project: 获取entry文件入口
 * @author: leinov
 * @date: 2018-10-11
 * @update: 2018-11-04 优化入口方法 调用getPath
 */
const getPath = require("./get-path");
/**
 * 【获取entry文件入口】
 *
 * @param {String} path 引入根路径
 * @returns {Object} 返回的entry { "about/aoubt":"./src/about/about.js",...}
 */
module.exports = function getEnty(path){
	let entry = {};
	getPath(path).map((item)=>{
		/**
		 * 下面输出格式为{"about/about":".src/aobout/index.js"}
		 * 这样目的是为了将js打包到对应的文件夹下
		 */
		entry[`${item}/${item}`] = `${path}/${item}/index.js`;
	});
	return entry;
};

这里我们使用getFilepath获取的数组,在获取到每个目录下的js文件,组合成一个js入口文件的如下格式的对象。

{
    "index/index":"./src/index/index.js",
    "todo/todo":"./src/todo/index.js"
}

在webpack中使用get-entry

const getEntry = require("./webpackConfig/get-entry");
const entry = getEntry();

module.exports = (env, argv) => ({
	entry: entry,
})

这样我们就自动获取到了entry

html-webpack-plugin自动配置

因为每个页面都需要配置一个html,而且每个页面的标题,关键字,描述等信息可能不同,所以我们在每个页面文件夹下创建一个pageinfo.json,通过fs模块获取到json里信息再遍历到对应得html-webpack-plugin中生成一个html插件数组。

index/pageinfo.json 生成index.html页面信息

{
    "title":"首页",
     "keywords":"webpack多页面"
}

todo/pageinfo.json 生成todo.html页面信息供

{
    "title":"todo list",
    "keywords":"todolist react"
}

通过fs遍历读取并生成HtmlWebpackPlugin数组供webpack使用

遍历html插件数组

/**
 * @file 页面html配置
 * @author:leinov
 * @date: 2018-10-09
 * @update: 2018-11-05
 * @use: 动态配置html页面,获取src下每个文件下的pageinfo.json内容,解析到HtmlWebpackPlugin中
 */

const fs = require("fs");
const HtmlWebpackPlugin = require("html-webpack-plugin");//生成html文件
const getPath = require("./get-path");
let htmlArr = [];
function createHtml(page_path){
	getPath(page_path).map((item)=>{
		let infoJson ={},infoData={};
		try{
			// 读取pageinfo.json文件内容,如果在页面目录下没有找到pageinfo.json 捕获异常
			infoJson = fs.readFileSync(`${page_path}/${item}/pageinfo.json`,"utf-8");//
			infoData = JSON.parse(infoJson);
		}catch(err){
			infoData = {};
		}
		htmlArr.push(new HtmlWebpackPlugin({
			title:infoData.title ? infoData.title : "webpack,react多页面架构",
			meta:{
				keywords: infoData.keywords ? infoData.keywords : "webpack,react,github",
				description:infoData.description ? infoData.description : "这是一个webpack,react多页面架构"
			},
			chunks:[`${item}/${item}`], //引入的js
			template: "./src/template.html",
			filename : item == "index" ? "index.html" : `${item}/index.html`, //html位置
			minify:{//压缩html
				collapseWhitespace: true,
				preserveLineBreaks: true
			},
		}));
	});
	return htmlArr;
}


module.exports = createHtml;

wbpack终极配置

const path = require("path");
const createHtml =require("./config/create-html");// html配置
const getEntry = require("./config/get-entry");
const entry = getEntry("./src/pages");
const htmlArr = createHtml("./src/pages");

module.exports = (env, argv) => ({
    entry: entry
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    }
    ....//其他配置
    devServer: {
	port: 3100,
	open: true,
    },
    plugins: [
        ...htmlArr
    ]
})

这样一个自动化完整的多页面架构配置就完成了,如果我们要新创建一个页面

    1. 在src下创建一个文件目录
    1. 在新创建的文件目录下添加index.js(必须,因为是webpack打包入口文件)
    1. 在新创建文件夹下添加pageinfo.json(非必须) 供html插件使用
    1. npm run dev开发
      完整代码参考项目code

疑惑

想问一下rem布局在哪儿配置的?没有看到

使用element-react,element-theme-default,页面打开空白,无报错

问题详情:
1.element-theme-default里面的css均带有@符号,打包时无法识别@符号,报错如下:
ERROR in ./~/element-theme-default/lib/index.css Module parse failed:
/home/tak/workspace/react/FT/node_modules/element-theme-default/lib/index.css
Unexpected character '@' (1:0) You may need an appropriate loader to
handle this file type. SyntaxError: Unexpected character '@' (1:0)
2.修改webpack.config.js,如下:

  	{
  		test: /\.css$/,
  		use: [ "style-loader","css-loader"],
  		// exclude: /node_modules/,       注释了这一行
  	},
  	{
  		test: /\.(ttf|eot|svg|woff|woff2)(\?.+)?$/,        //新增了对字符的处理
  		loader: 'file-loader'
  	},

打包成功
3.npm run dev 会额外生成style.js及字符文件,结构如下:

|-- build
    |-- index
        |-- index.css
        |-- index.js
    |-- todo
        |-- index.html
        |-- todo.css
        |-- todo.js
    |-- index.html
    |-- style.js
    |-- xxxxx.ttf
    |-- xxxxx.woff

找不到问题所在,应该是打包环节出现了问题,请指点

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.