webpack配合gulp构建一个前端项目

我现在的项目用的是fis+gulp+webpack来构建的项目,要说的是gulp已经足够优秀,我们只是在打包按需加载js文件时,使用了webpack。

因为fis为之前为百度内部构件工具,所以生态圈并不丰富,所以并不推荐全部使用fis来构建项目。

使用webpack配置文件( 主要是exports moudle resolve plugins的配置 )如下:

module.exports = {
    devtool: "source-map",    //生成sourcemap,便于开发调试
    entry: getEntry(),         //获取项目入口js文件
    output: {
        path: path.join(__dirname, "dist/js/"), //文件输出目录
        publicPath: "dist/js/",        //用于配置文件发布路径,如CDN或本地服务器
        filename: "[name].js",        //根据入口文件输出的对应多个文件名
    },
    module: {
        //各种加载器,即让各种文件格式可用require引用
        loaders: [
            // { test: /\.css$/, loader: "style-loader!css-loader"},
            // { test: /\.less$/, loader: "style-loader!csss-loader!less-loader"}
        ]
    },
    resolve: {
        //配置别名,在项目中可缩减引用路径
        alias: {
            jquery: srcDir + "/js/lib/jquery.min.js",
            core: srcDir + "/js/core",
            ui: srcDir + "/js/ui"
        }
    },
    plugins: [
        //提供全局的变量,在模块中使用无需用require引入
        new webpack.ProvidePlugin({
            jQuery: "jquery",
            $: "jquery",
            // nie: "nie"
        }),
        //将公共代码抽离出来合并为一个文件
        new CommonsChunkPlugin('common.js'),
        //js文件的压缩
        new uglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ]
};复制代码

webpack的配置思路是每个页面一个入口文件,文件中可以通过require引入其他模块,而这些模块webpack会自动跟入口文件合并为一个文件。
在module.exports中的 entry: getEntry()来获取入口文件getEntry()方法可以生成文件的绝对路径 map 如:

entry:{
    news-detail: /../Document/project/.../news-detail.js
}复制代码

之后再通过output就会在output.path路径下生成[name].js,即news-detail.js,文件名保持相同。

module 的作用是添加loaders, 那loaders有什么作用呢?
如果我们想要在js文件中通过require引入模块,比如css或image,那么就需要在这里配置加载器,这一点对于React来说相当方便,因为可以在组件中使用模块化CSS。而一般的项目中可以不用到这个加载器。

resolve 中的alias可以用于定义别名,用过seajs等模块工具的都知道alias的作用,比如我们在这里定义了ui这个别名,那么在模块中想引用ui目录下的文件,就可以直接这样写:
require('ui/dialog.js'); //前面不需要加上更长的文件名

plugin 用于引入一些插件
我们这里使用了CommonsChunkPlugin用于生成公用代码,不只可以生成一个,还能根据不同页面的文件关系,自由生成多个,例如:

var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
    entry: {
        p1: "./page1",
        p2: "./page2",
        p3: "./page3",
        ap1: "./admin/page1",
        ap2: "./admin/page2"
    },
    output: {
        filename: "[name].js"
    },
    plugins: [
        new CommonsChunkPlugin("admin-commons.js", ["ap1", "ap2"]),
        new CommonsChunkPlugin("commons.js", ["p1", "p2", "admin-commons.js"])
    ]
};复制代码

在不同页面用script标签引入如下js:

page1.html: commons.js, p1.js
page2.html: commons.js, p2.js
page3.html: p3.js
admin-page1.html: commons.js, admin-commons.js, ap1.js
admin-page2.html: commons.js, admin-commons.js, ap2.js复制代码

这种用法有点像gulp或grunt中手动将多个js合并为common, 但是在webpack里,这个过程是全自动生成的,不用我们自己分析代码的依赖关系。但是这种按需加载的弊端也十分明显,需要人工配置需要提取的文件。
另外一个插件是uglifyJsPlugin,用于压缩js代码。

使用webpack 加载第三方库:(分两种情况第三方库在CDN或者在本地)

方法一 是在html中用script标签引入js文件,如

<script src="https://code.jquery.com/jquery-git2.min.js"></script>复制代码

然后再配置文件中添加externals

externals: { jquery: "jQuery" }复制代码

该字段的作用是将加jQuery全局变量变为模块可引入。然后在各个模块中,就可以如下使用:

var $ = require("jquery");复制代码

我个人觉得既然已经将加jQuery通过script引入了,那么就直接使用$标签就行了。不必再将其转化为模块。
方法二 是将jQuery代码保存到本地,在配置文件中添加:

resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }复制代码

即为jquery添加了别名,然后在模块中也是这样使用:

var $ = require("jquery");复制代码

还可以配合使用ProvidePlugin,其作用是提供全局变量给每个模块,这样就不需要在模块中通过require引入,例如:
使用前:

var _ = require("underscore");
_.size(...);
使用后:
plugins: [
  new webpack.ProvidePlugin({
    "_": "underscore"
  })
]

// If you use "_", underscore is automatically required
_.size(...)复制代码

总的来说,如果文件来自CDN,那么使用方法一,如果文件在本地,则用方法二。

gulp足够优秀
目前来说,我们只利用webpack进行了js方面的打包,其他功能用gulp就足够了。gulp主要做了下面几个工作:

  • css转化合并压缩
  • 图片的雪碧图合并和base64
  • 文件md5计算与替换
  • 热启动,浏览器自动刷新
    下列是依赖的npm模块:
    "devDependencies": {
    "gulp": "^3.8.10",
    "gulp-clean": "0.3.1",
    "gulp-concat": "2.6.0",
    "gulp-connect": "2.2.0",
    "gulp-css-base64": "^1.3.2",
    "gulp-css-spriter": "^0.3.3",
    "gulp-cssmin": "0.1.7",
    "gulp-file-include": "0.13.7",
    "gulp-less": "3.0.3",
    "gulp-md5-plus": "0.1.8",
    "gulp-open": "1.0.0",
    "gulp-uglify": "1.4.2",
    "gulp-util": "~2.2.9",
    "gulp-watch": "4.1.0",
    "webpack": "~1.0.0-beta6"
    },复制代码
    支持雪碧图合并和base64
    我对gulp-css-spriter和gulp-css-base64的源码做了一点修改,使其支持下面的语法:
    .icon_corner_new{
    background-image: url(../images/new-ico.png?__sprite);
    }复制代码
    如果在url的后面加上__sprite后缀,则插件将会把该图片合并到雪碧图里。可以支持一个css文件合并为一个雪碧图,也可以整站合并。
    .icon_corner_new{
    background-image: url(../images/new-ico.png?__inline);
    }复制代码
    如果加上后缀__inline,则会将图片转化为base64,直接添加到css文件中,对于几k的小文件可以直接使用inline操作。具体配置代码如下:
    gulp.task('sprite', function (done) {
    var timestamp = +new Date();
    gulp.src('dist/css/style.min.css')
        .pipe(spriter({
            spriteSheet: 'dist/images/spritesheet' + timestamp + '.png',
            pathToSpriteSheetFromCSS: '../images/spritesheet' + timestamp + '.png',
            spritesmithOptions: {
                padding: 10
            }
        }))
        .pipe(base64())
        // .pipe(cssmin())
        .pipe(gulp.dest('dist/css'))
        .on('end', done);
    });复制代码
    src为需要处理的css文件,spriteSheet为雪碧图生成的目标文件夹,pathToSpriteSheetFromCSS为css文件中url的替换字符串,spritesmithOptions是生成雪碧图的间隙。
    文件加md5, 实现发布更新
    发版本的时候为了避免浏览器读取了旧的缓存文件,需要为其添加md5戳。
    这里采用了gulp-md5-plus
    gulp.task('md5:js', function (done) {
    gulp.src('dist/js/*.js')
        .pipe(md5(10, 'dist/app/*.html'))
        .pipe(gulp.dest('dist/js'))
        .on('end', done);
    });复制代码
    该代码会将dist/js下面所有的js计算md5戳,并将dist/app/下的html中script中的src引用文件名替换为加了md5的文件名,再将md5文件替换到目标目录dist/js。css的md5操作跟js无异。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值