1190000003060016
It's been one months since I left Qunar and decided to stop using Fekit when I left. The decision was made not because Fekit was bad, but on the contrary, Fekit helped us do a lot of things and blocked many details, allowing developers to focus on the development process. However, with the upgrading of Fekit, there have been some problems, while Fekit and the company's business and release process has a certain coupling, so feel the use of open-source construction solutions.
In the process of using gulp, the basic is based on the use of Fekit ideas to gradually improve the construction process, so still want to thank Fekit. Now get to the chase
See how gulp can be used to implement local services, mock data, CSS preprocessing, JS modularity, packaging compression, version number substitution, and more.
1. Local Service
Dependent module: Gulp-webserver
Use:
gulp.task(‘webserver‘, function() { gulp.src(‘./app‘) .pipe(webserver({ livereload: true, directoryListing: { enable:true, path: ‘app‘ }, host: ‘172.16.100.27‘, port: 8000 }));});
Attention:
The app is your project directory, such as my directory results are as follows
-app |--- src |--- images |--- mock |--- prd |--- index.html-gulpfile.js
When you open directorylisting Enbale, you can access the root directory (172.16.100.27:8000) to display a list of directories or files.
Host can be IP or domain name, but in the virtual machine inside debugging, with the domain name access seems a bit of a problem, did not delve into, if you want to debug on the phone, it is also recommended to use IP.
2. Mock data
Dependent module: Gulp-webserver
Use: Please refer to the previous blog post Gulp mock data (analog, forward request)
3. CSS pre-processing compilation
Dependent module: Gulp-sass gulp-minify-css gulp-autoprefixer
Use: I'm using sass here.
var sass = require ( Span class= "hljs-string" > ' Gulp-sass '), minifycss = require ( Gulp-minify-css '), Autoprefix = require ( ' gulp-autoprefixer ' ); var cssfiles = [ ' app/src/styles/page/index.scss ', ' app/src/styles/page/touch.scss '; /* compile compressed Sass file */gulp.task ( ' sass ', function () {GULP.SRC (cssFiles) . Pipe (Sass (). On ( ' error ', sass.logerror)). Pipe (Autoprefix ()). Pipe (Minifycss ()). PIPE ( Gulp.dest (Paths.build.styles));
Attention:
When using the Sass module, add .on(‘error‘, sass.logError))
, so that the sass compile error will log, rather than terminate the run.
Autoprefix, this is a good thing, but also I do not need to fekit a reason (it has not integrated autoprefix)
4. JS Modular Development
Dependent module: Gulp-webpack gulp-uglify vinyl-named Imports-loader
Description: The COMMONJS modular approach of the Fekit, in addition to the Requirejs of this AMD modular approach. And Webpack is the ideal packaging tool, it supports both COMMONJS and AMD, and has a large number of loaders, including the above-mentioned SASS compilation, front-end template compilation and other loaders, but also Webpack-dev-server, has been strong enough to almost no need gulp. I am not familiar with webpack, and need to use some other functions of gulp, so temporarily consider Webpack as a gulp module to use.
Use:
var named =Require' vinyl-named ');var webpack =Require' Gulp-webpack ');var jsfiles = [' App/src/scripts/page/index.js ',' App/src/scripts/page/touch.js '];Webpack Packing Compression Jsgulp.task (' Packjs ',function() {Return Gulp.src (jsfiles). Pipe (named ()). Pipe (Webpack ({output: {filename: ' [Name].js '}, module: {loaders: [{test: /\.html$/, loader: ' mustache '}, {test: /\.js$/, Loader: c5> "Imports?define=>false"}]}, resolve: {alias: {jquery: ' App/src/scripts/lib/jquery-1.11.3.min.js '}}, Devto OL: "#eval-source-map"}). Pipe (Uglify (). On (' error ', function(e) { console.log (' \x07 '), E.linenumber, E.message); return this.end ()})) . Pipe (Gulp.dest (paths.build.scripts);});
Attention:
-
For cases with multiple Ingress files (entry point), you need to use the Vinyl-named module so that you can implement the following packaging requirements
src/scripts/< Span class= "Hljs-keyword" >index.js-prd/scripts/index.jssrc/scripts/touch.js Prd/scripts/touch.js
in output you can set the package file name, such as Span class= "hljs-string" > "[Name].min.js"
-
I'm using Commonjs's modular approach to projects, but most plugins (like jquery or Zepto plugins) support two modular approaches, and are judged define again module.export, so we need to "block" How AMD modules are loaded.
first installs the ' imports-loader ' module and then configures the following:
module: {loaders: [{test:/\.js$/, loader: " Imports?define=>false "}]}
so we can use a variety of plugins with confidence.
-
My project uses HOGANJS as the front-end module, as long as the appropriate loader is found in the Webpack.
first installs [mustache-loader] ( https://github.com/deepsweet/mustache-loader) module, then do the following configuration:
module: {loaders: [{test:/\.html$/, loader: ' mustache '}]}
through 2. and 3. Two examples, you can see test is the type of file to be processed, and loader is the loader that handles the file.
Debugging is still a big problem, although Webpack provides a variety of debug modes (in the devtool
configuration, to implement Sourcemap debugging), but in practice, often encounter the problem of skipping breakpoints, Do not know is not gulp-webserver and webpack not fit the reason. So in the actual development, I will first uglify to comment out, so at least in a non-confusing compressed file debugging. If you have a good way, trouble to tell, thank you ~
5. Generate the MD5 (version number) corresponding to the file and add it when referencing the file in HTML
Dependent module: Gulp-rev gulp-rev-collector
Note: In the actual production environment, the CSS and JS files referenced by our page are all with the version number, so it is easy to roll back and prevent the cache. Usually we use the MD5 encoding of the file as the version number.
Use:
var rev =Require' Gulp-rev '), Revcollector =Require' Gulp-rev-collector ');var cssdistfiles = [' App/prd/styles/index.css '];var jsdistfiles = [' App/prd/scripts/index.js '];The PRD file is appended with the MD5 suffix and generates a replacement mapgulp.task (' Ver ',function () {gulp.src (cssdistfiles). Pipe (rev ()). PIPE ( Gulp.dest ( ' app/prd/styles ')) //generate NAME-MD5.CSS. PIPE ( Rev.manifest ()). Pipe (Gulp.dest (//generate Rev-manifest.json (map) gulp.src (jsdistfiles). Pipe (rev ()). Pipe (Gulp.dest (//HTML file Add MD5 reference Gulp.task ( ' html ', function () {GULP.SRC ([ ' App/ver/**/*.json ', ' app/*.html '). Pipe (Revcollector ()). PIPE ( Gulp.dest ( ' app/'));
The results are as follows:
index.html<script src="prd/scripts/index.js"></script>=><script src="prd/scripts/index-0884a4f91b.js"></script>
Attention:
I split the version number in the production MD5 and replace HTML into two steps, previously put together, and the result is an issue that replaces the file name in the HTML with the last version number.
6. Inline the externally referenced resource file into HTML
Dependent module: Gulp-inline-source
Description: Some of the active pages on touch, styles and scripts are not many, and instead of adding additional requests, it is better to embed the styles and scripts inline in the HTML file.
Use:
gulpfile.js// 把css、js以inline的形式插入htmlgulp.task(‘inlinesource‘, function () { return gulp.src(‘app/index.html‘) .pipe(inlinesource()) .pipe(gulp.dest(‘dist‘));});index.html<link rel="stylesheet" href="../prd/styles/index.css " inline><script src="../prd/scripts/index.js" inline></script>
In the last one months, I have used the basic so much, in fact, look back, their own patchwork is also built a small tool of their own. At the same time, I also have a deeper understanding of fekit design ideas and some principles.
However, like the FIS smarty template, Fekit velocity mock and other functions, I have not found how to implement in Gulp. Simply put, can be in the front-end environment to develop JSP, velocity or PHP (my current requirement is PHP), the data using a mock way, do not rely on the backend, so that the control of the view completely to the front end, to achieve the separation of front and back (non-Ajax mode). If you have any suggestions, please advise!
Updated 08.11
7, the template level of the front and rear end separation
Dependent module: Gulp-swig
Description: Swig is a class Django, twig template front-end templates, said to be similar, the basic syntax is actually the same, so the front-end development with Swig, backend with the corresponding template engine (such as Python Django, PHP with Twig, etc.), so that a set of templates can be resolved in front and back , which enables separation of the front and rear ends.
Since swig and twig differ in some syntaxes, we need to extend the swig:
Swig.setdefaults ({cache:False, Loader:swig.loaders.fs (Path.join (appbase)), locals: {environment:"Local",Global variables, which represent the local environment, are used to differentiate between swig and Twig, where range:function(Start, end) {Return (NewArray (end-start+1). Join (). Split (', '). Map (function(N, IDX) {return idx + start; }); }}); Swig.setfilter (' Length ',function(input) {return input.length;}); Swig.setfilter ( ' slice ', functionreturn input.slice (begin, Len);}); Swig.setfilter ( ' Json_encode ', Functionreturn Json.stringify (input);}); Swig.setfilter ( ' replace ', Functionvar output = input; for (var key in obj) {output = Output.replace (key , Obj[key]); } return output;});
In addition, I set the environment in the locals field, so that in some places can be environment to determine whether the local environment, so as to resolve the problem of swig and twig incompatibility:
if environment == ‘local‘ %} {% set tpl_path = ‘./components/ctn_publish/‘ + type + ‘/index.tpl‘ %}{% else %} {% set tpl_path = ‘./components/ctn_publish/‘ ~ type ~ ‘/index.tpl‘ %}{% endif %}
Building a front-end project with gulp instead of Fekit