zoukankan      html  css  js  c++  java
  • 前端工程自动化构建总结

    前端自动化构建是当下的热门,我记得2014年的时候,前端的自动化构建,大多是用在javascript的合并、压缩、语法检查、coffeescript,Sass,LESS转换上,构建工具也有很多,比如ant,grunt,gulp等,二次封装的工具也有很多,比如百度的FIS,国外的Yeoman。2016年以后,随着es6,es7,Node的兴起,前端又发生了翻天覆的变化,特别是移动端的H5最为明显,以前切个图,在PC上预览测试就可以发布的时代,在移动端就不灵验了,在手机端预览至少要搭建一个http服务器,比如http://192.168.0.2/index.html。在手机端输入网址不方全,通常会将网址做成一个二维码,然后用手机扫一下就可以打开预览。我们每改一下样式,就在手机上点一下刷新或电脑上按一下F5,这在最初的时候,也不觉得有什么问题,因为拿到我手上的静态页,通常由切片的同事做好了兼容性测试,需要一边刷新浏览器,一边改样式的机会不多。随着我们尝试用Less,stylus,这样的css工具,一方面,需要用到gulp这样的工具在后台自动监听我们的样式改动,另一方面,手动刷新的时候,gulp的脚本未必转换完了。这时候迫切需要浏览器自动刷新。

    总的来说,需求就两点,一是需要一个http服务器,来供手机访问静态资源,另一个是监听代码的改动并自动刷新浏览器。要满足这两个需求的第三方工具,应当不难找,事实上像fis,yeoman,vuecli这样的工具应当都可以做到。可是我觉得它们都太复杂了,虽然我只用到其中一点点功能,但是我不得不仔细的通读他们的文档,找到自己需要的功能。有时候,官方说三分钟入门,可是我花三十分钟了还没有入门。或许我几天之后,我好不容易入门了,结果周围同事又给我推荐另一个工具,说比我手上这好一千倍,于是我又去学另一个工具。如此,很容易陷入不同工具之间的学习。更要命的是,转了一圈回来,其实我用的那一点功能,用哪一个工具都差不多,既不像A同学说的那么差劲,也不像B同学说的那么好。

    2015年6月份的时候,我们的项目开始用express+React.js做服务端渲染,Redux做状态管理。我们搭建了一套开发框架,以前那些自动化的工具,都不能完全满足我的需求了。js和css的改动越来越频繁,而且node不像php代码那样,改动之后,服务器会自动更新,它需要手动重启node进程,另一方面,自动刷新浏览器,会导致redux的action日志看不到。这个时候,浏览器的自动刷新已经满足不了我们的需求。我们需要浏览器在不刷新的情况下,局部更新我改过的代码。这也就是“热替换”(HMR)这个概念的来由。很多新同事搞不清什么是自动刷新,什么是热替换。热替换听起来,有点像是ajax的效果,不过,ajax是点击某个动作或触发某个事件之后由js脚本触发,而“热替换"是在我们改动了代码的时候触发(也就是CTRL+S保存的时候). 自动刷新就是指不用手动去按F5. 

    要实现自动刷新和静态服务器,最简的就是用webpack-dev-server . 如果之前用过webpack,那么webpack-dev-server则很容易接受,如果还没有用过webpack,那么我觉得很有必要去看看。网上有很多介绍webpack及webpack-dev-server的文章,我觉得要这实现这个需求,只要两步就可以:

       1.安装webpack-dev-server

       2. 运行webpack-dev-server --inline --hot

    webpack.config.js的配置:

    var path = require("path");
    var webpack = require('webpack');
    //var ExtractTextPlugin = require("extract-text-webpack-plugin");
    var node_modules_dir = path.resolve(__dirname, 'node_modules');
     
    module.exports = {
    	entry:[
    	 	//'webpack-dev-server/client?http://localhost:8081',
        	     //'webpack/hot/dev-server',
    		'./src/app.jsx','./src/app.css'
    	],
    	module: {
        	loaders: [{
    		    test: /.es6|jsx$/,
    		    exclude: [node_modules_dir],
    		    loaders: ['react-hot','babel-loader'],
    	    },
    	    {
    	    	test:/.css$/,
    	    	loaders:['style', 'css']
    	    }]
      	},
    	output: {
    		path: path.resolve(__dirname, "dist"),
    		publicPath:"/assets/",
        	filename: 'bundle.js'
     	},
     	resolve: {
        	extensions: ['', '.js','.es6','.jsx']
        },
     	plugins: [
     		new webpack.DefinePlugin({
    		    'process.env.NODE_ENV': '"development"'
    		}),
    		//new webpack.HotModuleReplacementPlugin(),
    		new webpack.NoErrorsPlugin()
        ]
    }
    

    通过命令行的方式执行webpack-dev-server , 重点要说的是--hot这个参数,它就是启动热替换用的。它会自动给plugins插入new webpack.HotModuleReplacementPlugin() 因此不需要人为的再配置这个插件了。所以我在webpack.config.js中注释掉了这一行。 然后entry中也不需要加webpack/hot/dev-server和webpack-dev-server/client,记住:命令行方式运行webpack-dev-server会自动替你完成这些工作。不要人云亦云的去添加这些注释的内容,我看到甚至还有用express配合webpack-hot-middleware,webpack-dev-middleware 之类的用法,那更加复杂了,对于只想要实现自动刷新和热替换来说,命令行方式运行,配合 --hot --inline 这两个参数是最简单有效的做法。其它复杂的配置和用法,有它的特殊的适用场景,比如同时需要两个服务器,一个充当数据接口,一个充当静态文件服务器, 我们希望webpack-dev-server通过node API的方式运行。这个有点复杂,用到这么复杂的情形的,一般都是能自己搞定这个配置的。有这方面需求的,参考demo8的代码。 

    填坑记

    extract-text-webpack-plugin这个插件,它可以将模块中的样式部分提出来,单独打包成文件,但是它只适用于生产模式。开始我也没有注意,在开发模式下也用了,还觉得很爽,直到有一次,我发现更改样式的时候,浏览器居然自动刷新了,而我期望是热替换。这时我才理解,只适用于生产模式,不是说它在开发模式下,就不生效了,而是它配合 --hot参数的时候,不会有热替换的效果。

    简单的一行小字,没有细看,结果走了很多弯路。俗话说,方向反了,停止就是进步。 对于普通的js模块来说,热替换需要自己写loader插件,如果是react,vue则官方会提供热替换的loader,比如react的 react-hot-loader 。如果没有用这些可以支持热替换的插件,那么默认的就是浏览器的自动刷新效果。css的话,只要加上css-loader,style-loader就可以了。最后再补一刀,output:中要配publicPath

    output: {
    		path: path.resolve(__dirname, "dist"),
    		publicPath:"/assets/",
        	        filename: 'bundle.js'
     	},
    

    在html中也要写publickPath的地址:

    /assets/这个虚拟目录中的文件实际上是保存在内存中的,这样就为模块的热替换提供了可能。如果写成实际的产出目录,是怎么也不会看到热替换的效果的,甚至连自动刷新都不会出现.

    源码地址:https://github.com/bjtqti/how_to_use_webpack/tree/master/demo18

    验证是否成功开启HMR

    首先看控制台的提示:

    出现这个HMR说明配置方面是对的,但是光有这个还不行,如果模块没有热替换的loader,那么就会触发失败,失败的结果就是导致浏览器刷新。这也是为什么有时候明明出现这个热替换的标志了,还是会出现浏览器刷新。如果添加了支持热替换的loader,那么当我们保存更改的时候,浏览器只会默默的更新变化区域,而不会产生刷新。同时,控制台的log也会累积,不会被清空。

    手机预览

    辛苦做出来的H5页面,在电脑上模拟显示的效果,都未必可靠,最后都需要放到手机上进行真机检测。通过webpack-dev-server生成的http服务器,可以实现通过手机访问。比如电脑的ip是192.168.1.122, 默认情况下,那么通过http://191.168.1.122:8080就可以在手机上打开我们的H5页面。如果打不开,请检查两个地方:

     1. webpack-dev-server 添加 --host 0.0.0.0 参数

     2. 保证电脑和手机处于同一个无线网络,即电脑可以ping通手机。

    打包发布

    在手机上检测完好之后,就需要把代码进行合并,压缩,添加hash标记,小图片,字体文件转base64,提取共公代码等等.  一方面可以简单的使用

    webpack -p 也可自行配置webpack.config.js,演示:

     plugins: [
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': '"production"'
            }),
            new ExtractTextPlugin('css/[name].css'),
            new webpack.optimize.UglifyJsPlugin({
                compress: {
                    warnings: false
                },
                output: {
                  comments: false
                },
                sourceMap: false
            }),
            new webpack.optimize.CommonsChunkPlugin('vendor','js/vendor.js'),
            new webpack.optimize.OccurenceOrderPlugin(true),
            new webpack.NoErrorsPlugin()
        ]
    

      

    到此,整个构建工作就完成了。

    小结

    关于webpack及webpack-der-server的教程很多,但是很多文章发布的较早,不一定适用你现在用的版本。遇到问题的时候,我建议先看看错误提示,然后查看官方文档。先从简单的用法开始去动手尝试,一定要尝试,不要觉得很简单,只在脑海里想当然的运行一遍就以为学会了,俗话说,实践出真知,同样的问题,不同的环境(windows/mac/node版本...),会有不同的情况,只有自己一一去试过了,遇到问题心中有数,才不会慌。最后,要把学到的内容结合实际的项目去运用看看,有哪些功能对目前的开发有帮助,哪些功能还不是很了解,需要更深入的学习。遇到实在有自己找不到解决办法的问题,再去网上查,个人觉得stockoverflow还算比较靠谱。最后,要记得把自己遇到的坑整理成章,分享是一种美德。

  • 相关阅读:
    【业务自动化】iTop,全面支持ITIL流程的一款ITSM工具
    【Hadoop】HDFS源码解读
    【Hadoop】Hadoop RPC框架线程模型
    电商网站项目(一)用户模块---门户
    jdk1.5后枚举类的定义规则
    回顾static与final的作用
    @Springboot搭建项目controller层接收json格式的对象失败
    把一个文件中所有文件名或者文件路径读取到一个txt文件,然后在matlab中读取
    springboot用mybatis-generator自动生成mapper和model
    hibernate、mybatis、spring data 的对比
  • 原文地址:https://www.cnblogs.com/afrog/p/6258044.html
Copyright © 2011-2022 走看看