1.npm install webpack --save-dev
2.安装加载器
npm install babel-loader --save-dev
npm install babel-core --save-dev
npm install babel-preset-es2015 --save-dev //es6转码规则
npm install style-loader --save-dev
npm install css-loader --save-dev
npm install less --save-dev
npm install less-loader --save-dev //样式加载器
npm install extract-text-webpack-plugin --save-dev //分离css
3.配置webpack.config.js
var webpack=require("webpack"); var ExtractTextPlugin=require("extract-text-webpack-plugin"); // 分离css var path=require("path"); var fs=require("fs"); function getEntry(){ var jsPath="./src/js/"; var dirs=fs.readdirSync(jsPath); var matchs=[], files={}; dirs.forEach(function (item) { matchs=item.match(/(.+)\.js$/); if (matchs){ files[matchs[1]]=path.resolve(jsPath,item); } }); return files; }; module.exports = { // 入口文件位置 entry:getEntry(), // 输出文件位置 output:{ path:"./dist/", publicPath:"./dist/", filename:"[name].js" }, module:{ // require加载时编译 loaders:[ { test:/\.js$/, exclude:/node_modules/, loaders:["babel-loader"] }, { test:/\.less$/, loader:ExtractTextPlugin.extract("style-loader","css-loader!less-loader") } ] }, resolve:{ extensions:["",".coffee",".js"], // 配置别名,方便require alias:{ asset:__dirname+"/asset/", /*jquery:__dirname+"/asset/js/jquery-1.12.2.min.js", bootstrap:__dirname+"/asset/bootstrap/", bootstrapTable:__dirname+"/asset/bootstrap-table/",*/ } }, // 外部文件形式 externals:{ jquery:'window.jQuery' }, plugins:[ // 提供全局变量,无须require载入 new webpack.ProvidePlugin({ jQuery:"jquery", $:"jquery" }), // 自动抽离公共代码 new webpack.optimize.CommonsChunkPlugin('common.js'), // 分离css new ExtractTextPlugin("[name].css"), /*// 压缩js文件 new webpack.optimize.UglifyJsPlugin({ compress:{ warnings:false } })*/ ] };
4.配置.babelrc
{ "presets":["es2015"] }
5.编译webpack --display-error-details
6.生成测试文件
var fs=require("fs"); var path=require("path"); var jsPath="./src/",testPath="./test/",demo="test.html"; function createTestFile(source,target){ var dirs=fs.readdirSync(source); dirs.forEach(function(item){ var stat=fs.statSync(path.join(source,item)); if ( stat.isDirectory() ){ if ( !fs.existsSync(path.join(target,item)) ){ fs.mkdirSync(path.join(target,item)); }; createTestFile(path.join(source,item),path.join(target,item)); }else{ var file=item.slice(0,item.indexOf(".")); var suffix=item.slice(item.indexOf(".")+1); if ( !path.join(target,file+".html") ){ var html=fs.readFileSync(path.join(testPath,demo),"utf8"); fs.writeFileSync(path.join(target,file+".html"),html, {encoding:"utf8"}); }; }; }); }; createTestFile(jsPath,testPath);
7.测试文件demo
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css"/> <script src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script> <script src="../dist/common.js" type="text/javascript"></script> <script src="../dist/index.js" type="text/javascript"></script> </head> <body> <h1 id="qunit-header">QUnit测试</h1> <h2 id="qunit-banner"></h2> <div id="qunit-testrunner-toolbar"></div> <h2 id="qunit-userAgent"></h2> <ol id="qunit-tests"></ol> <div id="qunit-fixture">测试标记</div> </body> <script type="text/javascript"> var a; module("sum",{ // 在每个测试之前运行 setup: function(){ a=23; }, // 在每个测试之后运行 teardown: function(){ } }); test("sum", function(){ equal( sum(a,2), 4, "匹配" ); }); /*// 异步测试1 test("async", function() { stop();// 终止qunit测试 $.getJSON("resource", function(result) { deepEqual(result, { status: "ok" }); start(); }); }); // 异步测试2 asyncTest("async2", function() { expect(1);// 判断1次 $.getJSON("resource", function(result) { deepEqual(result, { status: "ok" }); start(); }); }); // 测试抛出错误,raises第二个参数为正则或构造函数,判断错误是否构造函数的实例 test("raises", function() { function CustomError() {} raises(function() { throw new CustomError(); }, CustomError, "must throw error to pass"); }); // 添加测试方法 function domEqual( selector, modifier, message ) { var attributes = ["class", "role", "id", "tabIndex", "aria-activedescendant"]; function extract(value) { var result = {}; result.nodeName = value[0].nodeName; $.each(attributes, function(index, attr) { result[attr] = value.attr(attr); }); result.children = []; var children = value.children(); if (children.length) { children.each(function() { result.children.push(extract($(this))); }); } else { result.text = value.text(); } return result; } var expected = extract($(selector)); modifier($(selector)); var actual = extract($(selector)); QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); }*/ </script> </html>
备注:
被依赖的模块不能作为entry中的配置项
与gulp相结合
1.npm install gulp --save-dev
2.npm install webpack-stream --save-dev //gulp-webpack插件
3.配置gulpfile.js
var gulp=require("gulp"); var webpack=require("webpack");// 模块化加载 var webpackConfig=require("./webpack.config.js");// webpack配置文件 var less=require("gulp-less");// 编译less var minifycss=require("gulp-clean-css");// 压缩css var watch=require("gulp-watch");// 通过监听实时启动gulp任务 var rename=require("gulp-rename");// 文件重命名 var notify=require("gulp-notify");// 控制台打印工具 var dash="\n\n--------------------------------\n\n"; var paths={ scripts:"src/js/*.js", less:"src/css/*.less" } gulp.task("webpack",function(callback){ var myConfig=Object.create(webpackConfig); webpack(myConfig,function(err,stats){ callback(); }); }); gulp.task("less",function(){ gulp.src("src/css/*.less") .pipe( less() ) .pipe( gulp.dest("public/dist/css") )// 输出未压缩文件 .pipe( minifycss() ) .pipe( rename( {suffix:'.min'} ) ) .pipe( gulp.dest("public/dist/css") ) .pipe( notify({ message:"Compile less file successfully."}) );// 输出压缩文件 }); gulp.task("server",function(){ require("./app.js"); console.log(dash+"KOA server is running at http://127.0.0.1:3005/."+dash) }); gulp.task("watch",function(){ gulp.watch(paths.less,["less","server"]); gulp.watch(paths.scripts,["webpack","server"]); }) gulp.task("default",["webpack","less","server","watch"]);
4.webpack.config.js同单独使用webpack时