gulp + webpack 搭建项目环境

搭建一个 gulp + webpack 的环境去学 react ,环境没有区分生产和开发环境,后续会完善,新手可以看一下。

项目目录:
config
- webpack.configjs // webpack 配置信息
- configuration.init.js // 配置变量,例如输出目录等
public // 打包后的输出目录
src // 开发目录
- js
- css
- static
- views
- app.js
index.html
gulpfile.js
.babelrc


.babelrc // env 编译 es6,es7,react 等

{
  "presets": [
    [
      "env",
      {
        "targets": {
          "node": "current",
          "browsers": ["last 2 versions", "ie >= 7"]
        }
      }
    ]
  ]
}

configuration.init.js // 这里放一些配置的全局变量,后续可以把更多的配置加入

module.exports = {
  outPath: 'public' // 打包后输出到 public 目录
}

webpack.config.js


const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const configuration = require('./configuration.init.js')

const _path = path.resolve(__dirname, '../')

module.exports = {
  // 这里配置不同环境或不同需求的 webpack 配置,导出后在 gulp 引入
  dev: {
    entry: {
      app: path.resolve(_path, 'src/app.js'),
    },
    output: {
      path: `${path.resolve(_path)}/${configuration.outPath}`,
      filename: 'js/[name].[hash].js'
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel-loader',
          query: {
            presets: ['env', 'react', 'stage-0']
          }
        },
        {
          test: /\.scss$/,
          loader: ExtractTextPlugin.extract('css-loader?minimize!sass-loader')
        },
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract('style-loader!css-loader?minimize'),
        },
        {
          test: /\.(jpg|png)$/,
          loaders: ['url-loader']
        },
        {
          test: /\.json$/,
          loaders: ['json-loader'],
        }
      ],
    },
    plugins: [
      new webpack.optimize.CommonsChunkPlugin({
        name: 'common',
        filename: 'js/[name].[hash].js',
        minChunks: 3, // 有三个文件都用到才打包
      }),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false,
        },
      }),
      new ExtractTextPlugin(`css/[name].[hash].css`),
      new HtmlWebpackPlugin({
        // 打包 html 文件,并自动把打包后的加入 hash 值的 js,css 文件引入
        template: `${_path}/index.html`,
        filename: `${_path}/${configuration.outPath}/index.html`,
        // hash: true // js等文件后加 ?[hash]
      }),
    ],
    resolve: {
      extensions: ['.js', '.json', '.scss', '.png', 'jpg'],
    }
  }
}

gulpfile.js

const fs = require('fs')
const path = require('path')
const gulp = require('gulp')
const webpack = require('webpack')

const merge = require('merge-stream')
const runSequence = require('run-sequence') // 同步执行任务
const del = require('del')
const gulpLoadPlugins = require('gulp-load-plugins')
const browserSync = require('browser-sync')

const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

// 配置
const configuration = require('./config/configuration.init.js')
const webpackConfig = require('./config/webpack.config.js')

// 变量
const gulps = gulpLoadPlugins()
const version = parseInt(Math.random() * 10000000, 10) + 10000000
const con = {
  getType(val) {
    // 获取数据类型
    return Object.prototype.toString.apply(val).toLowerCase()
  },
   // 时间如果个位数加 0
  timeFormat(time) {
    time = this.getType(time) === '[object string]' ? time : String(time)
    return time.length === 1 ? '0' + time : time
  },
  // 得到 [12:23:01] 格式的时间
  getTime() {
    const nowTime = new Date()
    return `${this.timeFormat(nowTime.getHours())}:${this.timeFormat(nowTime.getMinutes())}:${this.timeFormat(nowTime.getSeconds())}`
  },
  // 终端彩色打印,col(1-6) 参数是颜色 
  // 无限链式调用,最后一个括号不能省略 con.log('aaa', 1)('bbb', 6)('ccc', 2)()
  // 最后的括号里如果加入 false 参数则不打印时间
  // 输出 => [00:00:00] aaabbbccc // 输出一串不同颜色的字符串
  log(text, col = 6) {
    let args = []
    args.push(`\x1b[3${col}m${text}\x1b[0m`)

    const fn_curry = (text_c, col_c = 6) => {
      if(text_c === void 0 || this.getType(text_c) === '[object boolean]') {
        text_c === void 0 || text_c === true ? args.unshift(`[\x1b[34m${this.getTime()}\x1b[0m] `) : null
        return console.log(args.join(''))
      } else {
        args.push(`\x1b[3${col_c}m${text_c}\x1b[0m`)
        return fn_curry }
    }
    return fn_curry
  },
}

// 清理文件
gulp.task('clean', () => del([`${configuration.outPath}/**/*`]));
// 复制文件
gulp.task('copy', () => {
  merge(
  // 图片
  gulp.src('./src/img/**/*')
    .pipe(gulps.changed(`./${configuration.outPath}/img`))
    .pipe(gulp.dest(`./${configuration.outPath}/img`)),
  // 复制图标
  gulp.src('./favicon.ico')
    .pipe(gulps.changed(`./${configuration.outPath}`))
    .pipe(gulp.dest(`./${configuration.outPath}`)) )
})

// webpack
gulp.task('webpack-dev', ['copy'], (callback) => {
  webpack(
    webpackConfig.dev, // webpack 打包配置导入 
  (err, stats) => {
    if (err) {
      console.log(err, 'err') } // 错误处理
    if (stats.compilation.errors.length > 0) {
      console.log(stats.compilation.errors[0].message, 'message')
    }
    // webpack 的打包信息另存为 txt 文件
  fs.writeFile(`${__dirname}/${configuration.outPath}/webpack.result.${stats.hash}.txt`, stats, (err) =>{
      if(err){
        console.log(err);
      }else{
        con.log(`webpack unpack info path: ${__dirname}/${configuration.outPath}/webpack.result.${stats.hash}.txt`, 5)()
      }
    })

    // webpack 输出日志
    con.log('******************\n\n', 2)()

    con.log(`${String(stats)}\n\n`, 4)()
    con.log('hash: ', 4)(stats.hash)()
    con.log('time: ', 4)(`${(stats.endTime - stats.startTime) / 1000}s`)()

    console.log('\n\n')
    con.log('******************', 2)()

    console.log('webpack-dev', 'done')
    callback()
  })
})

gulp.task('watch', function () {
  gulp.watch([
      `${__dirname}/src/**/*`,
  ], [
      'clean',
      'webpack-dev'
  ])
})

// 浏览器自动刷新
gulp.task('sync', () => {
  browserSync.init({
    proxy: 'localhost:10086',
    host: 'index.aaa.com',
    port: '10087',
    open: 'external',
  });
  gulp.watch(`${configuration.outPath}/**/*.*`).on('change', browserSync.create().reload);
})


// 默认任务
gulp.task('default', (cb) => {
  runSequence('clean', [
    'copy',
    'webpack-dev',
  ], cb)
});

// dev任务
gulp.task('dev', (cb) => {
  runSequence('clean', 'watch', [
    // 'sync',
    'copy',
    'webpack-dev',
  ], cb)
})

// build
gulp.task('build', (cb) => {
  runSequence('clean', [
    'copy',
    'webpack-dev',
  ], cb)
})


package.json

{
  "name": "react_test",
  "version": "1.0.0",
  "description": "this is a project for react practice",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "NODE_ENV=development gulp dev",
    "build": "npm run clean && NODE_ENV=production gulp build",
    "clean": "rm -rf public"
  },
  "author": "wenjiawei",
  "license": "ISC",
  "dependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "browser-sync": "^2.23.6",
    "css-loader": "^0.28.9",
    "del": "^3.0.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "gulp": "^3.9.1",
    "gulp-changed": "^3.2.0",
    "gulp-html-replace": "^1.6.2",
    "gulp-load-plugins": "^1.5.0",
    "html-webpack-plugin": "^2.30.1",
    "lodash": "^4.17.4",
    "merge-stream": "^1.0.1",
    "node-sass": "^4.7.2",
    "react": "^16.2.0",
    "react-dedux": "^0.4.0-beta.4",
    "react-dom": "^16.2.0",
    "react-redux": "^5.0.6",
    "react-router": "^4.2.0",
    "redux": "^3.7.2",
    "run-sequence": "^2.2.1",
    "sass": "^1.0.0-beta.4",
    "sass-loader": "^6.0.6",
    "style-loader": "^0.20.1",
    "webpack": "^3.10.0"
  }
}

原文链接:http://blog.csdn.net/qq_25243451/article/details/79248499

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值