美文网首页React专题
React多页面应用3(webpack性能提升,包括打包性能、提

React多页面应用3(webpack性能提升,包括打包性能、提

作者: 前端人人 | 来源:发表于2017-12-30 09:15 被阅读119次

    微信公众号首发!这边文章排版可能不好,请关注公众号,查看历史消息!

    本教程总共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

    当我们项目页面越来越多,依赖越来越多,打包时间会越来越长,那么我们如优化呢?

    1.打包性能问题 (涉及很多因素,我们慢慢来)

    引入依赖

    npm i -D cache-loader

    修改 webpack.dev.conf.js

    const webpack =require('webpack');//引入webpack

    const opn =require('opn');//打开浏览器

    const merge =require('webpack-merge');//webpack配置文件合并

    const path =require("path");

    const baseWebpackConfig =require("./webpack.base.conf");//基础配置

    const webpackFile =require("./webpack.file.conf");//一些路径配置

    let config = merge(baseWebpackConfig, {

    output: {

    path: path.resolve(webpackFile.devDirectory),

           filename:'js/[name].js',

           chunkFilename:"js/[name]-[id].js",

           publicPath:''

       },

       plugins: [

    /*设置开发环境*/

           new webpack.DefinePlugin({

    'process.env': {

    NODE_ENV: JSON.stringify('development'),

               }

    }),

           /*设置热更新*/

           new webpack.HotModuleReplacementPlugin(),

       ],

       module: {

    rules: [

    {

    test:/\.(js|jsx)$/,

                   use: [

    'cache-loader',

                       'babel-loader',

                   ],

                   include: [

    path.resolve(__dirname, "../../app"),

                       path.resolve(__dirname, "../../entryBuild")

    ],

                   exclude: [

    path.resolve(__dirname, "../../node_modules")

    ],

               },

               {

    test:/\.(css|pcss)$/,

                   loader:'style-loader?sourceMap!css-loader?sourceMap!postcss-loader?sourceMap',

                   exclude:/node_modules/

               },

               {

    test:/\.(png|jpg|gif|ttf|eot|woff|woff2|svg|swf)$/,

                   loader:'file-loader?name=[name].[ext]&outputPath=' +webpackFile.resource +'/'

               }

    ]

    },

       /*设置api转发*/

       devServer: {

    host:'0.0.0.0',

           port:8080,

           hot:true,

           inline:true,

           contentBase: path.resolve(webpackFile.devDirectory),

           historyApiFallback:true,

           disableHostCheck:true,

           proxy: [

    {

    context: ['/api/**', '/u/**'],

                   target:'http://192.168.12.100:8080/',

                   secure:false

               }

    ],

           /*打开浏览器 并打开本项目网址*/

           after() {

    opn('http://localhost:' +this.port);

           }

    }

    });

    module.exports = config;

    添加了如下代码

    use: [

    'cache-loader',

       'babel-loader',

    ],

    我们看下效果

    没有引入 cache-loader

    打包时间

    引入 cache-loader

    打包时间

    减少了3秒,再页面相当多的时候,优化是很明显的!

    2.提取公共包

    首先我们看下 首页 和 商城页 相同部分很不同部分

    几乎一模一样,好! 我们提取公共部分,放入一个组件中

    我们在 app-> component -> common 目录下 新建 Seconds.jsx 公共组件

    import Reactfrom 'react';

    class Secondsextends React.Component {

    constructor(props) {

    super(props);

           this.state = {seconds:0};

       }

    tick() {

    this.setState(prevState => ({

    seconds: prevState.seconds +1

           }));

       }

    componentDidMount() {

    this.interval =setInterval(() =>this.tick(), 1000);

       }

    componentWillUnmount() {

    clearInterval(this.interval);

       }

    render() {

    return (

                       这是{this.props.title}

                       Seconds: {this.state.seconds}

           );

       }

    }

    export default Seconds;

    改造 首页

    import Reactfrom 'react';

    import '../../public/css/index.pcss'

    import Secondsfrom '../common/Seconds'

    const Index = () =>

    ;

    export default Index;

    改造商城页

    import Reactfrom 'react';

    import '../../public/css/shop.pcss'

    import Secondsfrom '../common/Seconds'

    const Index = () =>

    ;

    export default Index;

    npm run dev 运行看下 是否正常

    一切正常

    3.开始提取

    目标是: 

    react react-dom 我们打包成 vendor.js  因为他们是第三方部,几乎不会变,除非你升级

    组件的公共部分 我们打包成 common.js

    组件独立的业务代码我们打包在对应的js文件中 如 index.js 或 shop.js

    改造 

    config -> webpack -> webpack.base.conf.js

    const json =require('../../package.json');//引进package.json

    const newEntry = {

    'index':'./entryBuild/index.js',

       'shop':'./entryBuild/shop.js',

    };

    newEntry.vendor = Object.keys(json.dependencies); //把 package.json dependencies字段的值放进 vendor中

    let config = {

    entry: newEntry,

       resolve: {

    extensions: [".js", ".json", ".jsx", ".css", ".pcss"],

       }

    };

    module.exports = config;

    改造 

    config -> webpack -> webpack.dev.conf.js

    const webpack =require('webpack');//引入webpack

    const opn =require('opn');//打开浏览器

    const merge =require('webpack-merge');//webpack配置文件合并

    const path =require("path");

    const baseWebpackConfig =require("./webpack.base.conf");//基础配置

    const webpackFile =require("./webpack.file.conf");//一些路径配置

    let config = merge(baseWebpackConfig, {

    output: {

    path: path.resolve(webpackFile.devDirectory),

           filename:'js/[name].js',

           chunkFilename:"js/[name]-[id].js",

           publicPath:''

       },

       plugins: [

    /*设置开发环境*/

           new webpack.DefinePlugin({

    'process.env': {

    NODE_ENV: JSON.stringify('development'),

               }

    }),

           /*设置热更新*/

           new webpack.HotModuleReplacementPlugin(),

           /* common 业务公共代码,vendor引入第三方 */

           new webpack.optimize.CommonsChunkPlugin({

    name: ["common", "vendor"],

           }),

           /* 防止 vendor hash 变化 */

    // extract webpack runtime and module manifest to its own file in order to

    // prevent vendor hash from being updated whenever app bundle is updated

           new webpack.optimize.CommonsChunkPlugin({

    name:'manifest',

               chunks: ['vendor']

    }),

       ],

       module: {

    rules: [

    {

    test:/\.(js|jsx)$/,

                   use: [

    'cache-loader',

                       'babel-loader',

                   ],

                   include: [

    path.resolve(__dirname, "../../app"),

                       path.resolve(__dirname, "../../entryBuild")

    ],

                   exclude: [

    path.resolve(__dirname, "../../node_modules")

    ],

               },

               {

    test:/\.(css|pcss)$/,

                   loader:'style-loader?sourceMap!css-loader?sourceMap!postcss-loader?sourceMap',

                   exclude:/node_modules/

               },

               {

    test:/\.(png|jpg|gif|ttf|eot|woff|woff2|svg|swf)$/,

                   loader:'file-loader?name=[name].[ext]&outputPath=' +webpackFile.resource +'/'

               }

    ]

    },

       /*设置api转发*/

       devServer: {

    host:'0.0.0.0',

           port:8080,

           hot:true,

           inline:true,

           contentBase: path.resolve(webpackFile.devDirectory),

           historyApiFallback:true,

           disableHostCheck:true,

           proxy: [

    {

    context: ['/api/**', '/u/**'],

                   target:'http://192.168.12.100:8080/',

                   secure:false

               }

    ],

           /*打开浏览器 并打开本项目网址*/

           after() {

    opn('http://localhost:' +this.port);

           }

    }

    });

    module.exports = config;

    添加了如下代码

    /*设置热更新*/

    new webpack.HotModuleReplacementPlugin(),

    /* common 业务公共代码,vendor引入第三方 */

    new webpack.optimize.CommonsChunkPlugin({

    name: ["common", "vendor"],

    }),

    /* 防止 vendor hash 变化 */

    // extract webpack runtime and module manifest to its own file in order to

    // prevent vendor hash from being updated whenever app bundle is updated

    new webpack.optimize.CommonsChunkPlugin({

    name:'manifest',

       chunks: ['vendor']

    }),

    改造 index.html

       react1

    添加了如下代码

    注:顺序不能变

    改造 shop.html

       react1

    注:顺序不能变

    发现没有 其实 index.html 和 shop.html  两个页面 很像 很像  是不是?  我们会再后面自动化生成页面中 来解决这个问题,就不用手动去新建了!

    npm run dev 看下效果

    没提取之前

    提取之后

    一切正常

    本文完

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

    感谢童鞋们支持!

    欢迎童鞋们留言!

    相关文章

      网友评论

        本文标题:React多页面应用3(webpack性能提升,包括打包性能、提

        本文链接:https://www.haomeiwen.com/subject/sldggxtx.html