相關依賴包css
cnpm i -D gulp-uglify gulp-cssmin gulp-minify-html gulp-rename
項目結構html
gulp ├── src │ ├── components │ │ ├── Test │ │ | └── index.jsx │ │ ├── Child │ │ | ├── index.css │ │ | └── index.jsx │ │ ├── Count │ │ | ├── index.css │ │ | └── index.jsx │ └── App.jsx ├── node_modules ├── index.js ├── gulpfile.js ├── index.html └── package.json
腳本node
// index.js import './src/App.jsx' // src/App.jsx import React from 'react' import { render } from 'react-dom' import Test from './components/Test/index.jsx' render(<Test />, document.getElementById("app")) // src\components\Test\index.jsx import React from 'react' import Child from '../Child/index.jsx' import Count from '../Count/index.jsx' export default class Test extends React.Component { state = { msg: 'hello, world' } render() { const { msg } = this.state return ( <React.Fragment> <Child msg={msg}/> <Count /> </React.Fragment> ) } } // src\components\Count\index.jsx import React from 'react' export default class Count extends React.Component { state = { count: 0, msg: '顯示一個計數器' } subFn = () => { this.setState((prevState, props) => ({ count: prevState.count - 1 })) } plusFn = () => { this.setState((prevState, props) => ({ count: prevState.count + 1 })) } render() { const { count, msg } = this.state return ( <div> <p className="count-text">{msg}</p> <div> <button onClick={this.subFn}>-</button> <span>{count}</span> <button onClick={this.plusFn}>+</button> </div> </div> ) } } // src\components\Count\index.css .count-text { font-size: 14px; font-family: Arial, Helvetica, sans-serif; font-weight: 400; color: red; } // src\components\Test\index.jsx import React from 'react' const Child = (props) => <div className="color">{props.msg}</div> export default Child // src\components\Test\index.css .color { color: red; }
構建腳本react
const path = require('path') const gulp = require('gulp') const babelify = require('babelify') const browserify = require('browserify') // 轉成stream流,gulp系 const source = require('vinyl-source-stream') // 轉成二進制流,gulp系 const buffer = require('vinyl-buffer') const { series, parallel } = require('gulp') const del = require('del') const concat = require('gulp-concat') const sass = require('gulp-sass') const cheerio = require('gulp-cheerio') const uglify = require('gulp-uglify') const cssmin = require('gulp-cssmin') const minifyHtml = require('gulp-minify-html') const rename = require('gulp-rename') const resolveDir = (dir) => path.resolve(__dirname, dir) const _path = { main_js: resolveDir('./index.js'), scss: ['./src/components/**/*.scss'], html: resolveDir('./index.html') } const clean = (done) => { del('./dist') done() } const _css = () => { return gulp.src(_path.scss) .pipe(sass()) .pipe(concat('app.css')) .pipe(cssmin()) .pipe(rename({suffix: '.min'})) .pipe(gulp.dest('./dist/css')) } const _script = () => { return browserify({ entries: _path.main_js, transform: [babelify.configure({ presets: ['@babel/preset-env', '@babel/preset-react'], plugins: [ '@babel/plugin-transform-runtime', ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties", { "loose": true }] ] })] }) .bundle() .pipe(source('app.js')) .pipe(buffer()) .pipe(uglify()) .pipe(rename({suffix: '.min'})) .pipe(gulp.dest('./dist/js')) } const _html = () => { return gulp.src(_path.html) .pipe(cheerio(($ => { $('script').remove() $('link').remove() $('body').append('<script src="./js/app.min.js"></script>') $('head').append('<link rel="stylesheet" href="./css/app.min.css">') }))) .pipe(minifyHtml({ empty: true, spare: true })) .pipe(gulp.dest('./dist')) } module.exports.build = series(clean, parallel(_script, _css, _html))
構建結果
npm
效果json