gulp webpack grunt requirejs



  1. 书写方式
    grunt 运用配置的思想来写打包脚本,一切皆配置,所以会出现比较多的配置项,诸如option,src,dest等等。而且不同的插件可能会有自己扩展字段,导致认知成本的提高,运用的时候要搞懂各种插件的配置规则。
    gulp 是用代码方式来写打包脚本,并且代码采用流式的写法,只抽象出了gulp.src, gulp.pipe, gulp.dest, gulp.watch gulp.task等接口,运用相当简单。经尝试,使用gulp的代码量能比grunt少一半左右。




  2. 任务划分
    gulp是工具链、构建工具,可以配合各种插件做js压缩,css压缩,less编译 替代手工实现自动化工作





1.构建工具 :  可以用构建基础项目



2.自动化 : 可以通过gulp.task配置各接口自动对js,css,html代码进行压缩, 自动刷新页面( IDE好多已经可以自动刷新了 )



3.提高效率用 : 可以编译less语法,可认快速对css的编辑



webpack是文件打包工具,可以把项目的各种js文、css文件等打包合并成一个或多个文件,主要用于模块化方案,预编译模块的方案



1.打包工具 : gulp 也可以,但是需要按项目配置属性项 , webpack 很集成了,简单



2.模块化识别



3.编译模块代码方案用



所以定义和用法上来说 都不是一种东西,无可比性 ,更不冲突!【当然,也有相似的功能,比如合并,区分,但各有各的优势】



  seajs / require : 是一种在线”编译” 模块的方案,相当于在页面上加载一个 CMD/AMD 解释器。这样浏览器就认识了 define、exports、module 这些东西。也就实现了模块化。



  browserify / webpack : 是一个预编译模块的方案,相比于上面 ,这个方案更加智能。没用过browserify,这里以webpack为例。首先,它是预编译的,不需要在浏览器中加载解释器。另外,你在本地直接写JS,不管是 AMD / CMD / ES6 风格的模块化,它都能认识,并且编译成浏览器认识的JS。这样就知道,Gulp是一个工具,而webpack等等是模块化方案。Gulp也可以配置seajs、requirejs甚至webpack的插件。



1,gulp更注重前端开发流程



2,webpack更注重模块化开发



Gulp和Webpack的基本区别:



gulp可以进行js,html,css,img的压缩打包,是自动化构建工具,可以将多个js文件或是css压缩成一个文件,并且可以压缩为一行,以此来减少文件体积,加快请求速度和减少请求次数;并且gulp有task定义处理事务,从而构建整体流程,它是基于流的自动化构建工具。



Webpack是前端构建工具,实现了模块化开发和文件处理。他的思想就是“万物皆为模块”,它能够将各个模块进行按需加载,不会导致加载了无用或冗余的代码。所以他还有个名字叫前端模块化打包工具。



就我而言,我在实际当中会将两种都选择混合使用。虽然两个都可以进行代码的压缩合并减少代码体积,但gulp.config.js中gulp的代码更加简单易懂,需要压缩合并谁就用哪个方法,而webpack样式合并需要在node环境下下载插件才能使用。另一点,gulp 是基于流的打包工具,需要谁,引用谁,并且他的压缩简单明了,后期维护起来方便,webpack则可以将具体的模块进行划分,需要哪个模块就加载哪个模块,实现按需加载,并且排除掉冗余代码,减少代码体积。



总结起来就是,gulp是基于流的自动化构建工具,但不包括模块化的功能,如果要用到的话,就需要引入外部文件,比如require.js等;而webpack是自动化模块打包工具,本身就具有模块化,并且也具有压缩合并的功能。二者侧重点不同,我认为相互结合使用会提高代码质量和代码的优化。




gulp的核心配置文件:
webpack的核心配置文件:



1,必须要有一个入口文件,入口文件是入口起点告诉 webpack 从哪里开始,并遵循着依赖关系图表知道要打包什么。可以将您应用程序的入口起点认为是根上下文(contextual root)或 app 第一个启动文件 入口文件需要我们自己创建,并在webpack.config.js中的entry:处写上正确路径



2,出口 将所有的资源(assets)归拢在一起后,我们还需要告诉 webpack 在哪里打包我们的应用程序。webpack 的 output 属性描述了如何处理归拢在一起的代码(bundled code)。



3加载器



webpack 的目标是,让 webpack 聚焦于项目中的所有资源(asset),而浏览器不需要关注考虑这些(这并不意味着资源(asset)都必须打包在一起)。webpack 把每个文件(.css, .html, .scss, .jpg, etc.) 都作为模块处理。而且 webpack 只理解 JavaScript。



webpack loader 会将这些文件转换为模块,而转换后的文件会被添加到依赖图表中。



在更高层面,webpack 的配置有两个目标。



识别出(identify)应该被对应的 loader 进行转换(transform)的那些文件
由于进行过文件转换,所以能够将被转换的文件添加到依赖图表(并且最终添加到 bundle 中)(use属性)
以上配置中,我们对一个单独的 module 对象定义了 rules 属性,里面包含两个必须属性:test 和 use。这可以告诉 webpack compiler 如下:



“嘿,webpack compiler,当你碰到「在 require()/import 语句中被解析为 ‘.js’ 或 ‘.jsx’ 的路径」时,在你把它们添加并打包之前,要先使用 babel-loader 去转换”。



W> 重要的是要记得,在 webpack 配置中定义 loader 时,要定义在 module.rules 中,而不是 rules。在定义错时 webpack 会提出严重的警告。



我们还有尚未提到的 loader,可以设定更多特定属性。



4,插件



插件是 wepback 的支柱功能。在你使用 webpack 配置时,webpack 自身也构建于同样的插件系统上!



webpack 插件是一个具有 apply 属性的 JavaScript 对象。 apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个 compilation 生命周期访问。



使用Gulp+Webpack
首先安装gulp require-dir
npm i -D gulp require-dir
在根目录新建文件 gulpfile.js
其中requireDir(传入的目录是gulp要读取的文件目录)
这里gulp目录里每个js文件就是一个gulp任务
gulp会读取所以js里定义的gulp任务名,与 default 任务为入口



default 任务
主要是用来整个任务, 整个流程就是
清除 => (编译, 这里用webpack做处理) => 文件压缩 =>启动服务器 => 监听文件 (改动文件时实时刷新)



clean任务
主要是清除已经打包生成的文件, 这里使用 del 模板, 如果要在管道中删除的话可以使用 vinyl-paths
其中 callback 用于解决异步操作问题, ‘!build/favicon.ico’ 取反不会被删除



文件压缩, 主要是 js, css以及图片
对js文件进行压缩时,如果js文件中具有ES6语法, 要先编译然后再压缩;



webpack
将 webpack 当成 gulp 的一个任务,对它进行操作
server
建立本地服务器,导出reload以便在其他文件中实现浏览器刷新



gulp 常用插件:



gulp-load-plugins:自动加载 package.json 中的 gulp 插件
gulp-rename: 重命名
gulp-uglify:文件压缩
gulp-concat:文件合并
gulp-less:编译 less
gulp-sass:编译 sass
gulp-clean-css:压缩 CSS 文件
gulp-htmlmin:压缩 HTML 文件
gulp-babel:使用 babel 编译 JS 文件
gulp-jshint:jshint 检查
gulp-imagemin:压缩 jpg、png、gif 等图片
gulp-livereload:当代码变化时,它可以帮我们自动刷新页面
Webpack 概念很多,但搞清楚 entry,output 和 loader 三个关键点,基本上就可以解决简单的问题了,稍微复杂的场景主要包括对资源的合并处理、分拆处理、多次打包等,部分这样的问题可以使用插件辅助解决,但是 Webpack 的强大并不在文件处理,而是依赖分析,所以在流程操作特别复杂的情况,webpack 并不能胜任工作,往往会被作为 gulp 的一个 task,整体工作流交给 gulp 主导。



webpack 常用的 loader 和 plugin:



Loader 列表



less-loader, sass-loader:处理样式
url-loader, file-loader:两个都必须用上。否则超过大小限制的图片无法生成到目标文件夹中
babel-loader,babel-preset-es2015,babel-preset-react:js 处理,转码
expose-loader: 将 js 模块暴露到全局
Plugin 列表



NormalModuleReplacementPlugin:匹配 resourceRegExp,替换为 newResource
ContextReplacementPlugin:替换上下文的插件
IgnorePlugin:不打包匹配文件
PrefetchPlugin:预加载的插件,提高性能
ResolverPlugin:替换上下文的插件
DedupePlugin:删除重复或者相似的文件
LimitChunkCountPlugin:限制打包文件的个数
UglifyJsPlugin:JS文件的压缩
CommonsChunkPlugin:共用模块提取
HotModuleReplacementPlugin:runtime时候的模块热替换
NoErrorsPlugin:跳过编译时出错的代码并记录,使编译后运行时的包不会发生错误。
HtmlWebpackPlugin:HTML模块的热更新




  1. Gulp 简介
    Gulp.js 是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务。Gulp.js 是基于 Node.js 构建的,利用 Node.js 流的威力,你可以快速构建项目并减少频繁的 IO 操作。Gulp.js 源文件和你用来定义任务的 Gulp 文件都是通过 JavaScript(或者 CoffeeScript )源码来实现的。



2.1 安装 Gulp
1 . 全局安装 gulp



npm install –global gulp
2 . 作为项目的开发依赖(devDependencies)安装:



npm install –save-dev gulp
我们全局安装了gulp,项目也安装了gulp,全局安装gulp是为了执行gulp任务,本地安装gulp则是为了调用gulp插件的功能。



2.2 配置Gulp
在项目根目录下创建一个名为 gulpfile.js 的文件,gulpfile.js是gulp项目的配置文件



var gulp = require(‘gulp’);



gulp.task(‘default’, function() {
// 将你的默认的任务代码放在这
});
2.3 运行gulp
在命令提示符执行 gulp 任务名称




gulp 或者 gulp default
2.4 清除文件
通过gulp删除某个文件夹的文件



1 . 安装 gulp-clean



npm i gulp-clean –save-dev
2 . 编写 gulpfile.js 代码



var clean = require(‘gulp-clean’);



gulp.task(‘clean’, function() {
return gulp.src([‘dist/css’, ‘dist/js’], { read: false })
.pipe(clean());
});
2.5 编译less
通过gulp编译LESS代码



1 . 安装 gulp-less



npm i gulp-less –save-dev
2 . 编写 gulpfile.js 代码



var less = require(‘gulp-less’);



gulp.task(‘styles’, function() {
return gulp.src(‘src/less/*.less’) //源文件路径
.pipe(less()) //less编译
.pipe(gulp.dest(‘dist/css’)) //目的路径
});
2.6 自动前缀
通过gulp处理css的自动前缀



1 . 安装 gulp-autoprefixer



npm i gulp-autoprefixer –save-dev
2 . 编写 gulpfile.js 代码



var autoprefixer = require(‘gulp-autoprefixer’);



gulp.task(‘styles’, function() {
return gulp.src(‘src/css/*.css’) //源文件路径
.pipe(autoprefixer()) //自动前缀
.pipe(gulp.dest(‘dist/css’)) //目的路径
});
2.7 base64编码
通过gulp将css中的图片转换成base65编码



1 . 安装 gulp-base64



npm i gulp-base64 –save-dev
2 . 编写 gulpfile.js 代码



var base64 = require(‘gulp-base64’);



gulp.task(‘styles’, function() {
return gulp.src(‘src/css/*.css’) //源文件路径
.pipe(base64()) //base64编码
.pipe(gulp.dest(‘dist/css’)) //目的路径
});
2.8 css压缩
通过gulp将css进行压缩



1 . 安装 gulp-minify-css



npm i gulp-minify-css –save-dev
2 . 编写 gulpfile.js 代码



var cssmin = require(‘gulp-minify-css’);



gulp.task(‘styles’, function() {
return gulp.src(‘src/css/*.css’) //源文件路径
.pipe(cssmin()) //css压缩
.pipe(gulp.dest(‘dist/css’)) //目的路径
});
2.9 排列文件顺序
通过gulp将js调整前后顺序



1 . 安装 gulp-order



npm i gulp-order –save-dev
2 . 编写 gulpfile.js 代码



var order = require(“gulp-order”);



gulp.task(‘scripts’, function() {
return gulp.src(‘src/js/*.js’) //源文件路径
.pipe(order([
“src/js/config.js”,
“src/js/index.js”
]))
.pipe(gulp.dest(‘dist/js’)) //目的路径
})
2.10 合并文件
通过gulp将多个文件进行合并



1 . 安装 gulp-concat



npm i gulp-concat –save-dev
2 . 编写 gulpfile.js 代码



var concat = require(‘gulp-concat’);



gulp.task(‘scripts’, function() {
return gulp.src(‘src/js/*.js’) //源文件路径
.pipe(concat(‘main.js’)) //合并文件
.pipe(gulp.dest(‘dist/js’)) //目的路径
})
2.11 重命名文件
通过gulp将文件名进行更改



1 . 安装 gulp-rename



npm i gulp-rename –save-dev
2 . 编写 gulpfile.js 代码



var rename = require(‘gulp-rename’);



gulp.task(‘scripts’, function() {
return gulp.src(‘src/js/*.js’) //源文件路径
.pipe(rename({

suffix: ‘.min’
})) //修改文件名

.pipe(gulp.dest(‘dist/js’)) //目的路径
})
2.12 JS文件压缩
通过gulp将js文件进行压缩



1 . 安装 gulp-uglify



npm i gulp-uglify –save-dev
2 . 编写 gulpfile.js 代码



var rename = require(‘gulp-rename’);



gulp.task(‘scripts’, function() {
return gulp.src(‘src/js/*.js’) //源文件路径
.pipe(uglify()) //压缩js
.pipe(gulp.dest(‘dist/js’)) //目的路径
})
2.13 图片压缩
通过gulp将图片进行压缩



1 . 安装 gulp-imagemin



npm i gulp-imagemin –save-dev
2 . 编写 gulpfile.js 代码



gulp.task(‘images’, function() {
return gulp.src(‘src/img/*’)
.pipe(cache(imagemin({
optimizationLevel: 3,
progressive: true,
interlaced: true
})))
.pipe(gulp.dest(‘dist/img’))
});
2.14 处理串行任务
定义多个任务的顺序执行关系,否则默认情况下,任务会以最大的并发数同时运行。



//清除任务
gulp.task(‘clean’, function() {
return gulp.src(‘dist/css’, { read: false })
.pipe(clean());
});



//编译任务
gulp.task(‘styles’, function() {
return gulp.src(‘src/less/*.less’) //源文件路径
.pipe(less()) //less编译

.pipe(gulp.dest(‘dist/css’)) //目的路径
});



//先清空目录,然后再执行编译CSS
gulp.task(‘default’, [‘clean’], function() {
gulp.start(‘styles’)
});
2.15 热加载服务
使用 BrowserSync 服务实现文件变更的实时编译调试



1 . 安装 browser-sync



npm i browser-sync –save-dev
2 . 编写 gulpfile.js 代码



var browserSync = require(‘browser-sync’).create();



gulp.task(‘dev’, function() {
//初始化browser-sync服务
browserSync.init({
server: {
baseDir: “./dist”
}
});



//检测less文件是否更改,来调用重新编译css
gulp.watch('src/less/*', ['styles']);

//如果css文件更改过则刷新服务器
gulp.watch( ['./dist/sys/css/*'] ).on("change", browserSync.reload) }); --



  1. Webpack 简介
    WebPack可以看做是模块打包机:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),从这个文件开始分析你的项目结构,找到项目的所有依赖文件,使用loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。



image.png



3.1 配置webpack
1 . 新建一个项目文件夹,并且安装webpack



mkdir webpack-demo && cd webpack-demo
npm init -y
npm install –save-dev webpack
2 . 新建html以及js文件如下





webpack








exports.printmsg = function(msg) {
console.log(msg);
}




var lib = require(‘./common.js’)
lib.printmsg(‘good’)
3 . 编译webpack



webpack src/js/index.js dist/bundle.js
可以看到打包结果如下:



$ webpack src/js/index.js dist/bundle.js
Hash: 39e1d99d27c58dd34eb1
Version: webpack 2.5.1
Time: 81ms
Asset Size Chunks Chunk Names
bundle.js 2.82 kB 0 [emitted] main
[0] ./src/js/common.js 58 bytes {0} [built]
[1] ./src/js/index.js 50 bytes {0} [built]
项目结构如下:



image.png



3.2 编写配置文件
Webpack拥有很多高级的功能,这些功能其实都可以通过命令行模式实现,但是正如已经提到的,这样不太方便且容易出错的,一个更好的办法是定义一个配置文件,这个配置文件其实也是一个简单的JavaScript模块,可以把所有的与构建相关的信息放在里面。下面来说明如何定义一个配置文件:



1 . 在根目录下面新建 webpack.config.js



var path = require(‘path’);



module.exports = {
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
}
};
2 . 修改 package.json,添加条目如下



{

“scripts”: {
“build”: “webpack”,
},

}
3 . 使用命令行编译项目



npm run build



3.3 调试webpack
开发总是离不开调试,如果可以更加方便的调试当然就能提高开发效率,不过打包后的文件有时候你是不容易找到出错了的地方对应的源代码的位置的,Source Maps就是来帮我们解决这个问题的。通过简单的配置后,Webpack在打包时可以为我们生成的source maps,这为我们提供了一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,也更容易调试。



devtool选项 配置结果
source-map 在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包文件的构建速度;
cheap-module-source-map 在一个单独的文件中生成一个不带列映射的map,不带列映射提高项目构建速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便;
eval-source-map 使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。不过在开发阶段这是一个非常好的选项,但是在生产阶段一定不要用这个选项;
cheap-module-eval-source-map 这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点;
在学习阶段以及在小到中性的项目上,eval-source-map 是一个很好的选项,不过记得只在开发阶段使用它,继续上面的例子,进行如下配置



var path = require(‘path’);
module.exports = {
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
devtool: ‘eval-source-map’
};



3.4 建立本地开发服务器
Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建,可以实现代码的热加载功能,可以通过它方便的进行代码的开发。其构建方法如下:



1 . 安装 webpack-dev-server



npm install –save-dev webpack-dev-server
2 . 修改配置文件 webpack.config.js



var path = require(‘path’);
module.exports = {
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
devServer: {
contentBase: “./”,
port: 9000,
inline: true
}
};
3 . 修改 package.json,添加条目如下



{

“scripts”: {
“dev”: “webpack-dev-server”,
},

}
4 . 输入 npm run dev 启动 webpack-dev-server



$ npm run dev




webpackproj@1.0.0 dev F:\Project\DEMO\webpackdemo

webpack-dev-server




Project is running at http://localhost:9000/

webpack output is served from /

Content not from webpack is served from ./

Hash: 1aca755d21fcb2c76314

Version: webpack 2.5.1

Time: 918ms

Asset Size Chunks Chunk Names

bundle.js 316 kB 0 [emitted] [big] main

bundle.js.map 375 kB 0 [emitted] main

chunk {0} bundle.js, bundle.js.map (main) 302 kB [entry] [rendered]

[35] (webpack)-dev-server/client?http://localhost:9000 5.68 kB {0} [built]

[36] ./src/js/index.js 69 bytes {0} [built]

[37] ./~/ansi-html/index.js 4.26 kB {0} [built]

[38] ./~/ansi-regex/index.js 135 bytes {0} [built]

[40] ./~/events/events.js 8.33 kB {0} [built]

[41] ./~/html-entities/index.js 231 bytes {0} [built]

[48] ./~/querystring-es3/index.js 127 bytes {0} [built]

[76] ./~/strip-ansi/index.js 161 bytes {0} [built]

[78] ./~/url/url.js 23.3 kB {0} [built]

[79] ./~/url/util.js 314 bytes {0} [built]

[80] (webpack)-dev-server/client/overlay.js 3.73 kB {0} [built]

[81] (webpack)-dev-server/client/socket.js 897 bytes {0} [built]

[83] (webpack)/hot/emitter.js 77 bytes {0} [built]

[84] ./src/js/common.js 58 bytes {0} [built]

[85] multi (webpack)-dev-server/client?http://localhost:9000 ./src/js/index.js 40 byte
s {0} [built]

+ 71 hidden modules

webpack: Compiled successfully.



3.5 配置HTML代码热加载
webpack-dev-server 只能监控入口文件(JS/LESS/CSS/IMG)的变化,因此 HTML文件的变化必须依赖插件来进行监控。



1 . 安装 html-webpack-plugin



npm install html-webpack-plugin –save-dev
2 . 修改配置文件 webpack.config.js, 把 index.html 加入监控



var path = require(‘path’);
var HtmlWebpackPlugin = require(‘html-webpack-plugin’)



module.exports = {
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
plugins: [
new HtmlWebpackPlugin({ // html代码热加载
template: ‘./index.html’
}),
],
devServer: {
contentBase: “./”,
port: 9000,
inline: true
}
};
此时可以取消 html 文件内的 js 引用,因为 html-webpack-plugin 会自动加载编译完的 js 文件





3.6 配置自动打开浏览器
通过配置 open-browser-webpack-plugin 可以在webpack编译完之后自动打开浏览器;



1 . 安装 open-browser-webpack-plugin



npm install open-browser-webpack-plugin –save-dev
2 . 修改配置文件 webpack.config.js



var path = require(‘path’);
var HtmlWebpackPlugin = require(‘html-webpack-plugin’)
var OpenBrowserPlugin = require(‘open-browser-webpack-plugin’);



module.exports = {
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
plugins: [
new HtmlWebpackPlugin({ // html代码热加载
template: ‘./index.html’
}),
new OpenBrowserPlugin({ //自动打开浏览器
url: ‘http://localhost:9000’
})
],
devServer: {
contentBase: “./”,
port: 9000,
inline: true
}
};



3.7 配置 json 加载器
使用 json 解析器可以将常量数据定义在 json文件中,然后在 js 文件中调用。



1 . 在项目根目录下面创建 config.json 文件,内容如下



{
“name”: “demo”,
“type”: “HTML5”
}
2 . 修改 index.js



var config = require(‘../../config.json’)
var lib = require(‘./common.js’)
lib.printmsg(config.name)
3 . 修改配置文件 webpack.config.js



var path = require(‘path’);



module.exports = {
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
module: {
rules: [{
test: /.json$/,
loader: “json-loader”
}]
}
};
项目结构如下:



image.png



3.8 配置 LESS 编译
1 . 安装 less style-loader css-loader less-loader



npm install less style-loader css-loader less-loader –save-dev
2 . 在项目的css目录下面创建 index.less 文件,内容如下



@charset “utf-8”;
@gray-base: #000;
@gray-light: lighten(@gray-base, 46.7%);



.g-index {
height: 100vh;
background: @gray-light;
}
3 . 修改 index.js



require(‘../css/index.less’)



var lib = require(‘./common.js’)
lib.printmsg(‘good’)
4 . 修改配置文件 webpack.config.js



var path = require(‘path’);



module.exports = {
devtool: ‘source-map’,
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
module: {
rules: [
{
test: /.less$/, // less解析器
loader: ‘style-loader!css-loader!less-loader’
},]
}
};
项目结构如下:



image.png



3.9 配置 Babel 编译
1 . 安装 babel-core babel-loader babel-preset-es2015



npm install babel-core babel-loader babel-preset-es2015 –save-dev
2 . 修改 common.js 为 ES6 格式



exports.printmsg = (msg) => {
console.log(msg);
}
3 . 修改配置文件 webpack.config.js



var path = require(‘path’);
module.exports = {
devtool: ‘source-map’,
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
module: {
rules: [{
test: /.js$/, //babel解析器
exclude: /node_modules/,
loader: ‘babel-loader’,
query: {
presets: [‘es2015’]
}
}]
}
};



3.10 配置 jQuery 解析器
1 . 安装 jquery



npm install jquery –save-dev
2 . 修改 index.js 调用 jquery 函数



require(‘jquery’)



$(init)
function init() {
var lib = require(‘./common.js’)
lib.printmsg(‘good’)
}
3 . 修改配置文件 webpack.config.js



var path = require(‘path’);
var webpack = require(‘webpack’);



module.exports = {
devtool: ‘source-map’,
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
module: {

rules: [{
test: /.js$/, //babel代码解析
exclude: /node_modules/,
loader: ‘babel-loader’,
query: {
presets: [‘es2015’]
}
}]
},
plugins: [
new webpack.ProvidePlugin({ //jquery解析器
$: “jquery”,
jQuery: “jquery”,
“window.jQuery”: “jquery”
})
]
};



3.11 配置 js 代码压缩
1 . 修改配置文件 webpack.config.js, 在 plugin 中添加 webpack.optimize.UglifyJsPlugin 模块



var path = require(‘path’);
var webpack = require(‘webpack’);
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;



module.exports = {
devtool: ‘source-map’,
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
module: { //在配置文件里添加JSON loader
rules: [{
test: /.js$/, //babel代码解析
exclude: /node_modules/,
loader: ‘babel-loader’,
query: {
presets: [‘es2015’]
}
}]
},
plugins: [
new uglifyJsPlugin({ //js代码压缩
compress: {
warnings: false
}
})
]
};





3.12 配置 eslint 语法解析
1 . 安装 esline 库



npm install eslint eslint-loader eslint-friendly-formatter eslint-plugin-html babel-eslint eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard –save-dev
2 . 在项目根目录下添加eslint 配置文件.eslintrc.js



// http://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parser: ‘babel-eslint’,
parserOptions: {
sourceType: ‘module’
},
env: {
browser: true,
},
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: ‘standard’,
// required to lint *.vue files
plugins: [
‘html’
],
// add your custom rules here
‘rules’: {
// allow paren-less arrow functions
‘arrow-parens’: 0,
“indent”: [2, 4],//缩进风格
‘no-undef’: 0,
// allow async-await
‘generator-star-spacing’: 0,
// allow debugger during development
‘no-debugger’: process.env.NODE_ENV === ‘production’ ? 2 : 0
}
}
3 . 修改配置文件 webpack.config.js



var path = require(‘path’);



module.exports = {
devtool: ‘source-map’,
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
module: {
rules: [{
test: /.js$/, //babel代码解析
exclude: /node_modules/,
loader: ‘babel-loader’,
query: {
presets: [‘es2015’]
}
}, {
test: /.js$/, //eslint语法解析
exclude: /node_modules/,
loader: ‘eslint-loader’,
enforce: ‘pre’,
options: {
formatter: require(‘eslint-friendly-formatter’)
}
}]
}
};



3.13 配置图片压缩器
1 . 安装 url-loader 库



npm install url-loader –save-dev
2 . 修改 index.less 文件



@charset “utf-8”;
@gray-base: #000;
@gray-light: lighten(@gray-base, 46.7%);



.g-index {
height: 100vh;
background: @gray-light;
background: url(‘../img/small.png’) no-repeat;
}
3 . 修改配置文件 webpack.config.js



var path = require(‘path’);
var webpack = require(‘webpack’);



module.exports = {
devtool: ‘source-map’,
entry: ‘./src/js/index.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
module: {
rules: [ {
test: /.less$/, // less解析器
loader: ‘style-loader!css-loader!less-loader’
}, {
test: /.(png|jpg)$/, // img压缩器
loader: ‘url-loader?limit=8192’
}]
}
项目结构如下:
image.png



3.14 配置公共库抽取
1 . 安装 chunk-manifest-webpack-plugin webpack-chunk-hash 库



npm install chunk-manifest-webpack-plugin webpack-chunk-hash –save-dev
3 . 修改配置文件 webpack.config.js



var path = require(‘path’);
var webpack = require(‘webpack’);
var HtmlWebpackPlugin = require(‘html-webpack-plugin’)
var WebpackChunkHash = require(“webpack-chunk-hash”);
var ChunkManifestPlugin = require(“chunk-manifest-webpack-plugin”);



module.exports = {
devtool: ‘source-map’,
entry: {
main: ‘./src/js/index.js’,
vendor: [‘jquery’]
},
output: {
filename: ‘[name].[chunkhash].js’,
path: path.resolve(__dirname, ‘dist’)
},
module: {
rules: [ {
test: /.less$/, // less解析器
loader: ‘style-loader!css-loader!less-loader’
}, {
test: /.(png|jpg)$/, // img压缩器
loader: ‘url-loader?limit=8192’
}]
},
plugins: [
new HtmlWebpackPlugin({ // html代码热加载
template: ‘./index.html’
}),
new webpack.ProvidePlugin({ //jquery解析器
$: “jquery”,
jQuery: “jquery”,
“window.jQuery”: “jquery”
}),
new webpack.optimize.CommonsChunkPlugin({ //公共库抽取
name: [“vendor”, “manifest”], // vendor libs + extracted manifest
minChunks: Infinity,
}),
new webpack.HashedModuleIdsPlugin(),
new WebpackChunkHash(),
new ChunkManifestPlugin({
filename: “chunk-manifest.json”,
manifestVariable: “webpackManifest”
})
]
};



3.15 配置模块分析器
在项目复杂的情况下,为了分析多个模块的相互依赖以及打包的关系,通常引入模块打包分析工具,可以清晰的给出每个模块的依赖关系。



1 . 安装 webpack-bundle-analyzer 库



npm install webpack-bundle-analyzer –save-dev
2 . 修改配置文件 webpack.config.js



Gulp构建工具
gulp是工具链,构建工具,可以配合各种插件做JS压缩,CSS压缩,less编译替代手动实现自动化工作.
所以它的主要作用是
1.构建工具
2.自动化
3.提高效率



Webpack打包工具
web是文件打包工具,可以把项目的各种js文件,css文件等打包合成一个或多个文件,主要用于模块化方案,预编译模块的方案
所以它的主要作用是
1.打包工具
2.模块化识别
3.编译模块代码方案



Grunt是一个任务执行者,有大量现成的插件封装了常见的任务,也能管理任务之间的依赖关系,自动化执行依赖的任务,每个任务的具体执行代码和依赖关系写在配置文件 Gruntfile.js 里,例如:



在项目根目录下执行命令 grunt dev 就会启动 JavaScript 文件压缩和自动刷新功能。



Grunt的优点是:



灵活,它只负责执行你定义的任务;
大量的可复用插件封装好了常见的构建任务。
Grunt的缺点是集成度不高,要写很多配置后才可以用,无法做到开箱即用。



Gulp 是一个基于流的自动化构建工具。 除了可以管理和执行任务,还支持监听文件、读写文件。Gulp 被设计得非常简单,只通过下面5种个方法就可以胜任几乎所有构建场景:



通过 gulp.task 注册一个任务;
通过 gulp.run 执行任务;
通过 gulp.watch 监听文件变化;
通过 gulp.src 读取文件;
通过 gulp.dest 写文件。
Gulp 的最大特点是引入了流的概念,同时提供了一系列常用的插件去处理流,流可以在插件之间传递,



Webpack与Grunt、Gulp运行机制


grunt gulp 思路


【遍历源文件】->【匹配规则】->【打包】
做不到按需加载,对打包的资源,是否用到,打包过程不关心。



webpack


【入口】->【模块依赖加载】->【依赖分析】->【打包】
在加载、分析、打包的过程中,可以针对性的做一些解决方案。比如:code split(拆分公共代码)



Grunt与Gulp性能比较
Grunt: 每个任务处理完成后存放在本地磁盘.tmp目录中,有本地磁盘的I/O操作,会导致打包速度比较慢。
Gulp: gulp与grunt都是按任务执行,gulp有一个文件流的概念。每一步构建的结果并不会存在本地磁盘,而是保存在内存中,下一个步骤是可以使用上一个步骤的内存,大大增加了打包的速度。


Category web