• 1.React多页面应用1(webpack开发环境搭建,包括Babel、热更新等) ----2017.12.28 2.React多页面应用2(处理CSS及图片,引入postCSS及图片处理等)----2017.12.29 3.React多页面应用


    本教程总共7篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章!


    1.React多页面应用1(webpack开发环境搭建,包括Babel热更新等) ----2017.12.28


    2.React多页面应用2(处理CSS及图片,引入postCSS及图片处理等)----2017.12.29


    3.React多页面应用3(webpack性能提升,包括打包性能、提取公共包等)----2017.12.30


    4.React多页面应用4(webpack自动化生成多入口页面)----2017.12.31


    5.React多页面应用5(webpack生产环境配置,包括压缩js代码,图片转码等)----2018.01.01


    6.React多页面应用6(gulp自动化发布到多个环境,生成版本号,打包成zip等)----2018.01.02


    7.React多页面应用7(引入eslint代码检查)----2018.01.03


    开发环境:Windows 8,node v8.9.1,npm 5.5.1,WebStorm 2017.2.2


    在之前课程中,我们发现,有很多重复劳动

    如:

    我们需要手动新建webpack入口文件

    再 entryBuild 文件夹中新建,每个页面的js文件

    index.js

    shop.js


    这两个文件 几乎是一样的


    然后还需要在 build 文件夹中建立

    两个对应的 html文件

    index.html


    shop.html


    这两个文件几乎也是一样的

    顺便还有一个问题就是 

    title 如何设置?

    描述 和 关键词 如何设置?

    我们现在来解决这些问题!!!!!!!!!!


    1. 设置 entry 入口文件

      我们在 config 文件夹中 新建 entry.js ,以后我们新建页面,只需要在这里添加即可

      path路径 会指向到 app->component 目录下

    let entry = [
    {
    name: 'index',
           path: 'index/Index.jsx',
           title: '首页',
           keywords: '首页,xxx',
           description: '这是我们的首页'
       },
       {
    name: 'shop',
           path: 'shop/Index.jsx',
           title: '商城',
           keywords: '商城,xxx',
           description: '这是我们的商城'
       }
    ];
    module.exports = entry;


    2.接下来 我们要实现 自动化 生成 , webpack 的入口文件js,和html文件

    在这之前我们需要写几个公共方法!

    在config下,新建common

    建立copyFile.js

    // js/app.js:指定确切的文件名。
    // js/*.js:某个目录所有后缀名为js的文件。
    // js/**/*.js:某个目录及其所有子目录中的所有后缀名为js的文件。
    // !js/app.js:除了js/app.js以外的所有文件。
    // *.+(js|css):匹配项目根目录下,所有后缀名为js或css的文件。

    //流 stream   管道 pipe 管道
    //如果想在读取流和写入流的时候做完全的控制,可以使用数据事件。但对于单纯的文件复制来说读取流和写入流可以通过管道来传输数据。
    /*
    * 复制目录中的所有文件包括子目录
    * @src param{ String } 需要复制的目录   例 images 或者 ./images/
    * @dst param{ String } 复制到指定的目录    例 images images/
    */
    const fs = require("fs");
    const path = require("path");
    //获取当前目录绝对路径,这里resolve()不传入参数
    const filePath = path.resolve();

    const copy = function(src,dst){

    //判断文件需要时间,则必须同步
       if(fs.existsSync(src)){
    fs.readdir(src,function(err,files){
    if(err){console.log(err);return;}
    files.forEach(function(filename){

    //url+"/"+filename不能用/直接连接,Unix系统是”/“,Windows系统是”\“
                   var url = path.join(src,filename),
                       dest = path.join(dst,filename);
                   console.log(url);
                   console.log(dest);
                   fs.stat(path.join(src,filename),function(err, stats){
    if (err) throw err;

                       //是文件
                       if(stats.isFile()){

    //创建读取流
                           readable = fs.createReadStream(url);
                           //创建写入流
                           writable = fs.createWriteStream(dest,{ encoding: "utf8" });
                           // 通过管道来传输流
                           readable.pipe(writable);

                           //如果是目录
                       }else if(stats.isDirectory()){
    exists( url, dest, copy );
                       }
    });
               });
           });
       }else{
    console.log("给定的目录不存,读取不到文件");
           return;
       }
    };

    function exists(url,dest,callback){
    fs.exists(dest,function(exists){
    if(exists){
    callback && callback(url,dest);
           }else{
    //第二个参数目录权限 ,默认0777(读写权限)
               fs.mkdir(dest,0777,function(err){
    if (err) throw err;
                   callback && callback(url,dest);
               });
           }
    });
    }
    module.exports = copy;

    建立deleteFile.js

    const fs = require("fs");
    const deleteFolderRecursive = function (path) {
    if (fs.existsSync(path)) {
    fs.readdirSync(path).forEach(function (file, index) {
    let curPath = path + "/" + file;
               if (fs.lstatSync(curPath).isDirectory()) { // recurse
                   deleteFolderRecursive(curPath);
               } else { // delete file
                   fs.unlinkSync(curPath);
               }
    });
           fs.rmdirSync(path);
       }
    };

    module.exports = deleteFolderRecursive;

    建立 imgDel.js

    let fs = require('fs');
    let join = require('path').join;

    /**
    *
    * @param startPath  起始目录文件夹路径
    * @returns {Array}
    */
    function findSync(startPath) {
    let result = [];

       function finder(path) {
    let files = fs.readdirSync(path);
           files.forEach((val, index) => {
    let fPath = join(path, val);
               let stats = fs.statSync(fPath);
               if (stats.isDirectory()) finder(fPath);
               if(val.indexOf('png') !==-1 ||val.indexOf('gif') !==-1 || val.indexOf('jpg') !==-1){
    if (stats.isFile()) result.push(val.substring(0,val.length - 12));
               }
    });

       }

    finder(startPath);
       return result;
    }

    let fileNames = findSync('pc/resource/');
    console.log(fileNames);

    建立 nodeCommon.js

    const deleteFile = require("./deleteFile");
    const copyFile = require("./copyFile");
    module.exports = {
    deleteFile,
       copyFile
    };

    建完后目录结构如下


    3.新建entryBuild.js

    const fs = require("fs");
    const path = require("path");
    const entry = require('./entry');
    const nodeCommon = require('../common/nodeCommon');

    const entryBuildPath = path.resolve(__dirname, '../../entryBuild');
    nodeCommon.deleteFile(entryBuildPath);
    fs.mkdirSync(entryBuildPath);

    const entryContent = (data) => {
    let cont = `<Index />`;
       return `
    import React from 'react';
    import ReactDOM from 'react-dom';
    import Index from '../app/component/${data.path}';
    ReactDOM.render(${cont},document.getElementById('app'));
       `
    };
    /*生成webpack entry 入口文件*/
    entry.map((data) => {
    fs.writeFile(entryBuildPath + '/' + data.name + '.js', entryContent(data), 'utf8', function (err) {
    if (err) {
    return console.log(err);
           }
    });
    });

    4.修改 package.json 

    "entry": "node config/entry/entryBuild.js",

    我们现在 删除 entryBuild 文件夹

    然后 执行 npm run entry

    看下 是不是 创建了 entryBuild  文件夹 及 index.js shop.js

    执行 npm run dev 

    一切正常


    5.接下来我们自动化生成 html文件

    我们需要建立一个模版 比如叫 index.html

    放在根目录下

    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta content="telephone=no" name="format-detection">
       <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
    <div id="app"></div>
    </body>
    </html>

    6.建立几个公用webpack js文件

    webpack.com.conf.js

    let titleFun = function(chunkName,title){
    let titleDef = 'XXX网站';
       if(chunkName.indexOf('index') !==-1){
    return titleDef;
       }else{
    return title + '_' + titleDef;
       }
    };
    module.exports = {
    titleFun:titleFun
    };


    添加依赖 

    npm i -D copy-webpack-plugin clean-webpack-plugin

    修改  webpack.file.conf.js 文件

    const path = require("path");
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    const CleanWebpackPlugin = require('clean-webpack-plugin');

    function cleanFun(arr) {
    return (new CleanWebpackPlugin(arr, {root: path.resolve(__dirname, '../../'), verbose: true, dry: false}))
    }

    let copyObj = [
    /*{from: './app/public/plugin', to: './plugin'},
       {from: './app/public/versionTips', to: './versionTips'},
       {from: './app/public/file', to: './resource'},
       {from: './app/public/img/favicon.ico', to: './'},*/
    ];

    let copyArr = [];
    copyObj.map((data) => {
    copyArr.push(
    new CopyWebpackPlugin([{from: data.from, to: data.to, ignore: ['.*']}])
    )
    });


    module.exports = {
    devDirectory: 'build', /*开发目录*/
       proDirectory: 'pc', /*发布目录*/
       resource: 'resource', /*静态资源*/
       resourcePrefix: '/static/pc/', /*线上静态资源前缀*/
       cleanFun: cleanFun,
       copyArr: copyArr,
       copyObj: copyObj
    };



    7.新建 webpack.devBuildHtml.conf.js

    const fs = require("fs");
    const nodeCommon = require("../common/nodeCommon");
    const webpackFile = require("./webpack.file.conf");
    const entryBuild = require('../entry/entry');
    const webpackComConf = require('./webpack.com.conf');
    /*删除构建目录*/
    nodeCommon.deleteFile(webpackFile.devDirectory);
    /*创建构建目录*/
    fs.mkdirSync(webpackFile.devDirectory);
    webpackFile.copyObj.map((data) => {
    let to = webpackFile.devDirectory + data.to.substring(1, data.to.length);
       if (data.to !== './') {
    fs.mkdirSync(to);
       }
    nodeCommon.copyFile(data.from, to);
    });
    /*生成HTML*/
    let htmlCont = fs.readFileSync("index.html", "utf-8");
    let scriptInsert = `
    <script type=text/javascript src=js/manifest.js></script>
    <script type=text/javascript src=js/vendor.js></script>
    <script type=text/javascript src=js/common.js></script>
    <script type=text/javascript src=js/key.js></script>
    `;
    htmlCont = htmlCont.replace('</body>', scriptInsert + '</body>');
    entryBuild.map((data) => {
    fs.writeFile(webpackFile.devDirectory + '/' + data.name + '.html',
           htmlCont.replace('js/key.js', 'js/' + data.name + '.js').replace('<%= htmlWebpackPlugin.options.title %>', webpackComConf.titleFun(data.name,data.title)),
           'utf8',
           function (err) {
    if (err) {
    return console.log(err);
               }
    });
    });

    8.修改package.json

    "devBuildHtml": "node config/webpack/webpack.devBuildHtml.conf.js",

    我们删除 根目录下的 build 文件夹,然后执行

    npm run devBuildHtml

    看下是否自动生成了 build 文件夹 和 index.html shop.html 文件


    9.添加 webpack.entry.conf.js

    const entryBuild = require('../entry/entry');
    let entry = {};
    entryBuild.map((data) => {
    entry[data.name] = ['./entryBuild/' + data.name + '.js', data.title];
    });
    module.exports = entry;


    10.改造webpack.base.conf.js   统一入口文件

    const entry = require("./webpack.entry.conf");
    const json = require('../../package.json');//引进package.json
    const newEntry = {};
    for (let name in entry) {
    newEntry[name] = entry[name][0]
    }
    newEntry.vendor = Object.keys(json.dependencies); //把 package.json dependencies字段的值放进 vendor中
    let config = {
    entry: newEntry,
       resolve: {
    extensions: [".js", ".json", ".jsx", ".css", ".pcss"],
       }
    };
    module.exports = config;


    11.运行

    npm run dev

    一切OK


    12.再往前走一步

    修改 package.json

    "devNew": "npm run entry && npm run devBuildHtml",




    以后我们再有新页面,只需要在 config\entry\entry.js中添加就可以了

    (目前 关键词,描述, 我们有去实现,也好实现,只是我们现在不太关注SEO,我只是预留了这个功能)


    然后 我们只需要

    有新页面的时候执行

    npm run devNew

    再执行

    npm run dev

    愉快的开发吧~~~~~~~~~~


    本文完 

    禁止擅自转载,如需转载请在公众号中留言联系我们!

    感谢童鞋们支持!

    欢迎童鞋留言!


    展开全文
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • 搭建react多页面应用 2019-04-16 11:54:16
    1.安装create-react-app npm install -g create-react-app 2.创建项目 create-react-app multifypages ...现在react应用页面已经可以运行起来了 5.然后进入src/App.js 用一下内容替换掉原有内容 impor...
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • 1.React多页面应用1(webpack开发环境搭建,包括Babel、热更新等) ----2017.12.28 2.React多页面应用2(处理CSS及图片,引入postCSS及图片处理等)----2017.12.29 3.React多页面应用3(webpack性能提升,包括打包...
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • React 多页面应用(新手) 2018-09-29 17:07:05
    https://www.jianshu.com/p/7ffdf1925d12
  • 现实中,应用往往包含很功能,这些功能无法通过一个页面展示,所以应用往往是‘多页面应用’。而且,用户在这些页面之间来回切换,开发者要做的就是保证用户的操作顺畅。最好的解决办法就是虽然逻辑上是‘多页面...
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • webpack4+react多页面架构 2018-10-15 16:50:17
    webpack在单页面打包上应用广泛,以create-react-app为首的脚手架众多,单页面打包通常是将业务js,css打包到同一个html文件中,整个项目只有一个html文件入口,但也有许多业务需要页面不同的入口,比如不同的h5...
  • 平时工作中会写一些多页面应用,因为习惯了react的开发模式,故此写了一个简单的配置,跟大家一起分享。如果你也喜欢,对你的开发有所帮助,希望给点鼓励(start) github地址:https://github.com/ivan-GM/Gm... ...
  • React多页面跳转 2018-06-12 17:44:24
    render () { const { app: { locationQuery } } = this.props; ////////////tolist.js const { 子页面数据 } = this.state; const { id } = locationQuery; ///获取当前页面地址栏的id const info = queryA...
  • 1.React多页面应用1(webpack开发环境搭建,包括Babel、热更新等) ----2017.12.28 2.React多页面应用2(处理CSS及图片,引入postCSS及图片处理等)----2017.12.29 3.React多页面应用
  • 1、React多页面应用1(webpack4 开发环境搭建,包括热更新,api转发等)---2018.04.042、React多页面应用2(webpack4 处理CSS及图片,引入postCSS,及图片处理等)---2018.04.083、React多页面应用3(webpack4 页面实现)---...
  • React + webpack 开发单页面应用简明中文文档教程(八)Link 跳转以及编写内容页面 在前面博文中,我们已经渲染了列表,并且用 Link 标签,来进行了跳转。但是我们并没有编写内容页面。这一篇,我们来解决这些问题...
  • React + webpack 开发单页面应用简明中文文档教程(一)一些基础概念 我之前写了一系列的 vue 相关的入门博文,深受大家的欢迎。现在开发了几个 reactjs 的小项目,略有心得,因此,想与大家分享。 由于之前有了 ...
1 2 3 4 5 ... 20
收藏数 37,776
精华内容 15,110