freyhill / react-multi-page-app Goto Github PK
View Code? Open in Web Editor NEW🍡 react multi page app/react多页面应用
Home Page: https://h5cool.com/react-multi-page-app/demo
License: MIT License
🍡 react multi page app/react多页面应用
Home Page: https://h5cool.com/react-multi-page-app/demo
License: MIT License
想问一下rem布局在哪儿配置的?没有看到
问题详情:
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
找不到问题所在,应该是打包环节出现了问题,请指点
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在单页面打包上应用广泛,以create-react-app为首的接触脚手架众多,单页面打包通常指的是将业务js,css打包到同一个html文件中,整个项目只有一个html文件入口
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 的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文件
这里我们需要用到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自己.
我们再看下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"
}
const getEntry = require("./webpackConfig/get-entry");
const entry = getEntry();
module.exports = (env, argv) => ({
entry: entry,
})
这样我们就自动获取到了entry
因为每个页面都需要配置一个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使用
/**
* @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;
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
]
})
这样一个自动化完整的多页面架构配置就完成了,如果我们要新创建一个页面
index.js
(必须,因为是webpack打包入口文件)pageinfo.json
(非必须) 供html插件使用npm run dev
开发服务器更新了文件,但是用户浏览器还是在用缓存的同名老文件
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.