日期:2014-05-16  浏览次数:20466 次

山寨一个js缩减comment的Maven Plugin
background:
动手写一个去掉js comment的Maven Plugin, 用英文写练习练习,哈哈

steps:

1. New a maven project, the pom is like below. At the beginning I do not add the maven project api to the project, it is exhausting to find the project strutcture, build path etc and filter the resources that i want. It is better to include it in my project,

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-plugin-api</artifactId>
			<version>2.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.maven</groupId>
			<artifactId>maven-project</artifactId>
			<version>2.0.9</version>
			<scope>provided</scope>
		</dependency>

	</dependencies>


2. Js comment is deleted by using regular expression. the code maybe like as below. The single line comment as "//...." without existing in string literal is hard to match. And a big js file is loaded into memory at one time and is treated as a really string by regular expression may cause java fatal error. So it is not very prefect, but it is enough to be fullfill my situation.
package com.mycompany.mojo.jsmin;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Pattern;

public abstract class JsFileProcessor {
	
	private static final int buffer_size = 512;
	
	private static final Pattern block = Pattern.compile( "(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)" );
	
	private static final Pattern singleLine = Pattern.compile( "(?<=.*)//[^\"\\n\\r]*(?=[\r\n])" );
	
	public static void process(File inputFile, File outputFile) throws IOException {
		
		FileInputStream fis = null;
		FileWriter fw = null;
		ByteArrayOutputStream baos = new ByteArrayOutputStream(buffer_size * 2);
		try {
			
			fis = new FileInputStream(inputFile);
			fw = new FileWriter(outputFile);
			
			int length = -1;
			byte[] buffer = new byte[buffer_size];
			while( (length = fis.read(buffer)) != -1) {
				
				baos.write(buffer, 0, length);
			}
			
		} catch (IOException e) {
			throw e;
		} finally {
			fis.close();
			baos.flush();
			baos.close();
		}
					
		String text = singleLine.matcher(
				block.matcher(baos.toString()).replaceAll("")	
				).replaceAll("");

		try {
			fw.write(text);
		} finally {
			fw.flush();
			fw.close();
		}
	}
}



3. Mojo is like as below, the annotation is required by Maven plugin to dependecy inject the parms value at runtime. It is really very convenient. to deal with resources. The plugin is binded to the life cycle: process-resources. When the war file is packaged, the comment-deleted js files may be overwritten.
package com.mycompany.mojo.jsmin;

import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.util.DirectoryScanner;

/**
 * delete the js file comment
 * @goal minify
 * @phase process-resources
 */
public class JsCommentMojo extends AbstractMojo {