使用Gulp和Browserify来搭建React应用程序

对React有一定了解之后,我们知道,需要把JSX文件转换成JS文件,组件需要导入导出。本篇就体验使用Gulp把JSX文件转换成JS文件,使用Browserify来把组件捆绑到一个文件并理顺组件之间的依赖关系。

Gulp是用来干嘛的呢?用来把Coffeescript, SASS, JSX等转换成浏览器能理解的JavaScript或CSS,再比如压缩文件到最小尺寸,再比如把文件捆绑到一个文件以减少请求次数,等等。

【文件结构】

node_modules/
gulpfile.js
Typler/
…..src/
……….index.html
……….js/
……………App.js
……………Child.js
……………Parent.js

【需求】

Development阶段:把JSX文件转换成JS文件,并保存到dist/src文件夹中;把src文件夹中的index.html文件复制到dist文件夹中

Product阶段:把所有的JS文件concat, minify, 最终绑定到一个文件build.js,把index.html中所有 <script></code>,替换成一个<code><script></code>标签。</p><p><strong>【index.html】</strong></p><pre><code><!DOCTYPE html> <html> <head></head> <body> <div id="app"></div></p> <pre><code> <script src="../../lib/react.js"></script> <script src="../../lib/react-dom.js"></script> <script src="../src/js/Child.js"></script> <script src="../src/js/Parent.js"></script> <script src="../src/js//App.js"></script> </code></pre> <p>

【Child.js】

var child = React.createClass({
    render: function(){
        return (
            <div>
                and this is the <b>{this.props.name}</b>.

            </div>
        )
    }
});

【Parent.js】

var Parent = React.createClass({
    render: function(){
        return (
            <div>
                <div>This is the parent.</div>
                <child name="child">
            </child></div>
        )
    }
});

【App.js】

ReactDOM.render(<parent>, document.getElementById('app'));
</parent>

【下载NPM Packages】

npm install --save-dev gulp
npm install --save-dev gulp-concat
npm install --save-dev gulp-uglify
npm install --save-dev gulp-react
npm install --save-dev gulp-html-replace

【gulpfile.js】

var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var react = require('gulp-react');
var htmlreplace = require('gulp-html-replace');

var path = {
    HTML: 'Tyler/src/index.html',
    ALL:['Tyler/src/js/*.js', 'Tyler/src/js/**/*.js','Tyler/src/index.html'],
    JS: ['Tyler/src/js/*.js', 'Tyler/src/js/**/*.js'],
    MINIFIED_OUT: 'build.min.js',
    DEST_SRC: 'Tyler/dist/src', //&#x628A;&#x4ECE;jsx&#x6587;&#x4EF6;&#x8F6C;&#x6362;&#x800C;&#x6765;&#x7684;&#x6587;&#x4EF6;&#x653E;&#x8FD9;&#x91CC;
    DEST_BUILD: 'Tyler/dist/build',
    DEST: 'Tyler/dist'
};

//&#x83B7;&#x53D6;js&#x7684;&#x6E90;&#x6587;&#x4EF6;&#xFF0C;&#x628A;jsx&#x8F6C;&#x6362;&#x6210;js&#xFF0C;&#x653E;&#x5230;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#x5939;
gulp.task('transform', function(){
    gulp.src(path.JS)
        .pipe(react())
        .pipe(gulp.dest(path.DEST_SRC))
})

//&#x628A;Tyler/src/index.html&#x8FD9;&#x4E2A;&#x6587;&#x4EF6;&#x590D;&#x5236;&#x653E;&#x5230;Tyler/dist&#x4E2D;
gulp.task('copy', function(){
   gulp.src(path.HTML)
    .pipe(gulp.dest(path.DEST));
});

//&#x89C2;&#x5BDF;index.html&#x548C;js&#x6587;&#x4EF6;&#x7684;&#x53D8;&#x5316;&#xFF0C;&#x6267;&#x884C;&#x4EE5;&#x4E0A;&#x7684;2&#x4E2A;&#x4EFB;&#x52A1;
gulp.task('watch', function(){
    gulp.watch(path.ALL, ['transform', 'copy']);
});

//&#x540D;&#x79F0;&#x4E3A;default&#x7684;task&#xFF0C;&#x9700;&#x8981;
gulp.task('default',['watch','transform', 'copy']);
  • transform这个task用来把jsx转换成js
  • copy这个task用来把Tyler/src/index.html复制拷贝到Tyler/dist/index.html
  • watch这个task用来观察js和html文件的变化,一旦有变化就执行transform和copy这个task
  • default是默认的task,一定需要,执行所有的task

现在执行gulp命令后,Tyler下多了dist文件夹,dist文件夹下多了index.html和src文件夹,src文件夹下有Child.js, Parent.js, App.js.

现在还剩下发布状态下的一些task,要做的事包括:

  • 先获取到所有的js文件
  • 把所有的js文件拼接起来
  • 最小化js文件
  • 把输出文件放到dist/build文件夹中

我们在gulp.js文件中增加如下:

//&#x53D1;&#x5E03;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x7684;task
gulp.task('build', function () {
    gulp.src(path.JS)
        .pipe(react())
        .pipe(concat(path.MINIFIED_OUT)) //&#x5408;&#x5E76;&#x5230;build.min.js&#x6587;&#x4EF6;&#x4E2D;
        .pipe(uglify(path.MINIFIED_OUT)) //&#x538B;&#x7F29;build.min.js&#x6587;&#x4EF6;&#x4E2D;
        .pipe(gulp.dest(path.DEST_BUILD));//&#x628A;build.min.js&#x6587;&#x4EF6;&#x653E;&#x5230;Tyler/dist/build&#x6587;&#x4EF6;&#x5939;&#x4E2D;
});

运行”gulp build”命令,这样,在Tyler/dist/build下多了一个合并压缩后的build.min.js文件。

但这里还有一个问题:Tyler/dist/index.html中依然引用的是src/js中的文件

    <script src="../src/js/Child.js"></script>
    <script src="../src/js/Parent.js"></script>
    <script src="../src/js//App.js"></script>

而我们需要引用的是如下这个文件:

<script src="build/build.min.js"></script>

gulp-html-replace就是为解决这个问题而存在。需要两步。

第一步:来到Tyler/src/index.html文件中,添加 <!--build:js--><!--endbuild-->指令。

<!DOCTYPE html>
<html>
    <head></head>
    <body>

        <script src="../../lib/react.js"></script>
        <script src="../../lib/react-dom.js"></script>
        <!-- build:js -->
        <script src="../src/js/Child.js"></script>
        <script src="../src/js/Parent.js"></script>
        <script src="../src/js//App.js"></script>
        <!-- endbuild -->
    </body>
</html>

第二步:添加task

//&#x5728;Tyler/dist/index.html&#x4E2D;&#x5F15;&#x7528;&#x7684;js&#x6587;&#x4EF6;&#x548C;Tyler/src/index.html&#x4E2D;&#x4E0D;&#x4E00;&#x6837;&#xFF0C;&#x9700;&#x8981;&#x66FF;&#x6362;
gulp.task('replaceHTML', function(){
   gulp.src(path.HTML)
    .pipe(htmlreplace({
       'js': 'build/' + path.MINIFIED_OUT
   }))
   .pipe(gulp.dest(path.DEST));
});

//&#x628A;&#x53D1;&#x5E03;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E4B;&#x524D;&#x7684;&#x6240;&#x6709;&#x4EFB;&#x52A1;&#x518D;&#x63D0;&#x70BC;
gulp.task('production', ['replaceHTML', 'build']);

运行:gulp production

再次来到Tyler/dist/index.html中,惊喜地发现如下:

<!DOCTYPE html>
<html>
    <head></head>
    <body>

        <script src="../../lib/react.js"></script>
        <script src="../../lib/react-dom.js"></script>
        <script src="build/build.min.js"></script>

    </body>
</html>

使用gulp-html-replace生效了!

最后,把完整的gulpfile.js呈现如下:

//Tyler

var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var react = require('gulp-react');
var htmlreplace = require('gulp-html-replace');

var path = {
    HTML: 'Tyler/src/index.html'
    , ALL: ['Tyler/src/js/*.js', 'Tyler/src/js/**/*.js', 'Tyler/src/index.html']
    , JS: ['Tyler/src/js/*.js', 'Tyler/src/js/**/*.js']
    , MINIFIED_OUT: 'build.min.js'
    , DEST_SRC: 'Tyler/dist/src', //&#x628A;&#x4ECE;jsx&#x6587;&#x4EF6;&#x8F6C;&#x6362;&#x800C;&#x6765;&#x7684;&#x6587;&#x4EF6;&#x653E;&#x8FD9;&#x91CC;
    DEST_BUILD: 'Tyler/dist/build'
    , DEST: 'Tyler/dist'
};

//&#x83B7;&#x53D6;js&#x7684;&#x6E90;&#x6587;&#x4EF6;&#xFF0C;&#x628A;jsx&#x8F6C;&#x6362;&#x6210;js&#xFF0C;&#x653E;&#x5230;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#x5939;
gulp.task('transform', function () {
    gulp.src(path.JS)
        .pipe(react())
        .pipe(gulp.dest(path.DEST_SRC))
})

//&#x628A;Tyler/src/index.html&#x8FD9;&#x4E2A;&#x6587;&#x4EF6;&#x590D;&#x5236;&#x653E;&#x5230;Tyler/dist&#x4E2D;
gulp.task('copy', function () {
    gulp.src(path.HTML)
        .pipe(gulp.dest(path.DEST));
});

//&#x89C2;&#x5BDF;index.html&#x548C;js&#x6587;&#x4EF6;&#x7684;&#x53D8;&#x5316;&#xFF0C;&#x6267;&#x884C;&#x4EE5;&#x4E0A;&#x7684;2&#x4E2A;&#x4EFB;&#x52A1;
gulp.task('watch', function () {
    gulp.watch(path.ALL, ['transform', 'copy']);
});

//&#x540D;&#x79F0;&#x4E3A;default&#x7684;task&#xFF0C;&#x9700;&#x8981;
gulp.task('default', ['watch', 'transform', 'copy']);

//&#x53D1;&#x5E03;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x7684;task
gulp.task('build', function () {
    gulp.src(path.JS)
        .pipe(react())
        .pipe(concat(path.MINIFIED_OUT)) //&#x5408;&#x5E76;&#x5230;build.min.js&#x6587;&#x4EF6;&#x4E2D;
        .pipe(uglify(path.MINIFIED_OUT)) //&#x538B;&#x7F29;build.min.js&#x6587;&#x4EF6;&#x4E2D;
        .pipe(gulp.dest(path.DEST_BUILD));//&#x628A;build.min.js&#x6587;&#x4EF6;&#x653E;&#x5230;Tyler/dist/build&#x6587;&#x4EF6;&#x5939;&#x4E2D;
});

//&#x5728;Tyler/dist/index.html&#x4E2D;&#x5F15;&#x7528;&#x7684;js&#x6587;&#x4EF6;&#x548C;Tyler/src/index.html&#x4E2D;&#x4E0D;&#x4E00;&#x6837;&#xFF0C;&#x9700;&#x8981;&#x66FF;&#x6362;
gulp.task('replaceHTML', function(){
   gulp.src(path.HTML)
    .pipe(htmlreplace({
       'js': 'build/' + path.MINIFIED_OUT
   }))
   .pipe(gulp.dest(path.DEST));
});

//&#x628A;&#x53D1;&#x5E03;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E4B;&#x524D;&#x7684;&#x6240;&#x6709;&#x4EFB;&#x52A1;&#x518D;&#x63D0;&#x70BC;
gulp.task('production', ['replaceHTML', 'build']);

以上,我们了解了有关gulp的好多方面,但这样的做法还有那些不足呢?

  • 需要手写各个组件的js文件位置
  • Parent.js依赖Child.js,需要手动让Child.js先与Parent.js加载
  • App.js依赖Parent.js,需要手动让Parent.js先与App.js先加载
  • 很难调试,很难知道jsx哪里出了问题

Browserify就是为了解决以上问题而存在的。

【Browserify+Gulp+React(Developement Tasks)】

安装NPM Packages

npm install --save-dev vinyl-source-stream
npm install --save-dev browserify
npm install --save-dev watchify
npm install --save-dev reactify
npm install --save-dev gulp-streamify

gulpfule.js

//Tyler using browserify

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var htmlreplace = require('gulp-html-replace');;
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify');
var streamify = require('gulp-streamify');

var path = {
    HTML: 'Tyler/src/index.html'
    , MINIFIED_OUT: 'build.min.js'
    , OUT: 'build.js'
    , DEST: 'Tyler/dist1'
    , DEST_BUILD: 'Tyler/dist1/build'
    , DEST_SRC: 'Tyler/dist1/src'
    , ENTRY_POINT: 'Tyler/src/js/App.js'
};

//Tyler/src/index.html&#x4E2D;&#x590D;&#x5236;&#x5230;TylerTyler/dist&#x4E2D;
gulp.task('copy', function () {
    gulp.src(path.HTML)
        .pipe(gulp.dest(path.DEST));
});

//&#x76D1;&#x6D4B;
gulp.task('watch', function () {

    //&#x76D1;&#x6D4B;html&#x6587;&#x4EF6;
    gulp.watch(path.HTML, ['copy']);

    //watchify&#x914D;&#x5408;browserify&#x4F7F;&#x7528;&#xFF0C;&#x56E0;&#x4E3A;&#x5355;&#x72EC;&#x4F7F;&#x7528;browserify&#x4F1A;&#x6BCF;&#x6B21;&#x904D;&#x5386;&#x6BCF;&#x4E2A;&#x7EC4;&#x4EF6;&#xFF0C;&#x4E00;&#x65E6;&#x6709;&#x53D8;&#x5316;&#x5C31;&#x4F1A;&#x91CD;&#x65B0;&#x751F;&#x6210;&#x7ED1;&#x5B9A;&#x6587;&#x4EF6;&#x3002;&#x800C;&#x6709;&#x4E86;watchify&#xFF0C;&#x4F1A;&#x7F13;&#x5B58;&#x6587;&#x4EF6;&#xFF0C;&#x53EA;&#x66F4;&#x65B0;&#x54EA;&#x4E9B;&#x53D1;&#x751F;&#x6539;&#x53D8;&#x7684;&#x6587;&#x4EF6;
    var watcher = watchify(browserify({
        entries: [path.ENTRY_POINT],//Tyler/src/js/App.js, browserify&#x4F1A;&#x68C0;&#x6D4B;Tyler/src/js&#x4E0B;&#x7684;&#x6240;&#x6709;js&#x6587;&#x4EF6;&#xFF0C;&#x4EE5;&#x53CA;Tyler/src/js&#x4E0B;&#x6240;&#x6709;&#x5B50;&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x7684;js&#x6587;&#x4EF6;
        transform: [reactify],//&#x4F7F;&#x7528;reactify&#x628A;jsx&#x8F6C;&#x6362;&#x6210;js&#x6587;&#x4EF6;
        debug: true,//&#x544A;&#x8BC9;Browersify&#x4F7F;&#x7528;source maps, souce maps&#x5E2E;&#x52A9;&#x6211;&#x4EEC;&#x5728;&#x51FA;&#x73B0;&#x9519;&#x8BEF;&#x7684;&#x65F6;&#x5019;&#x5B9A;&#x4F4D;&#x5230;jsx&#x4E2D;&#x7684;&#x9519;&#x8BEF;&#x884C;
        cache: {},//&#x5FC5;&#x987B;&#x7684;&#xFF0C;browserify&#x544A;&#x8BC9;&#x6211;&#x4EEC;&#x8FD9;&#x6837;&#x4F7F;&#x7528;
        packageCache: {},//&#x5FC5;&#x987B;&#x7684;&#xFF0C;browserify&#x544A;&#x8BC9;&#x6211;&#x4EEC;&#x8FD9;&#x6837;&#x4F7F;&#x7528;
        fullPath: true//&#x5FC5;&#x987B;&#x7684;&#xFF0C;browserify&#x544A;&#x8BC9;&#x6211;&#x4EEC;&#x8FD9;&#x6837;&#x4F7F;&#x7528;
    }));

    return watcher.on('update', function(){
        watcher.bundle()//&#x628A;&#x6240;&#x6709;&#x7684;jsx&#x6587;&#x4EF6;&#x7ED1;&#x5B9A;&#x5230;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;
            .pipe(source(path.OUT))
            .pipe(gulp.dest(path.DEST_SRC));

        console.log('Updated');
    })
        .bundle()
        .pipe(source(path.OUT))
        .pipe(gulp.dest(path.DEST_SRC));
});

//&#x9ED8;&#x8BA4;&#x7684;task
gulp.task('default', ['watch']);

运行gulp命令,在Tyler文件夹下多了dist1文件夹。

【Browserify + Gulp + React(Production Tasks)】

&#x5728;&#x53D1;&#x5E03;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E4B;&#x524D;&#xFF0C;&#x9700;&#x8981;&#x6DFB;&#x52A0;&#x5982;&#x4E0B;task

//&#x53D1;&#x5E03;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E4B;&#x524D;
gulp.task('build', function () {
            browserify({
                    entries: [path.ENTRY_POINT]
                    , transform: [reactify]
                })
                .bundle()
                .pipe(source(path.MINIFIED_OUT))
                    .pipe(streamify(uglify(path.MINIFIED_OUT)))
                    .pipe(gulp.dest(path.DEST_BUILD));
                });

gulp.task('replaceHTML', function () {
    gulp.src(path.HTML)
        .pipe(htmlreplace({
            'js': 'build/' + path.MINIFIED_OUT
        }))
        .pipe(gulp.dest(path.DEST));
});

gulp.task('production', ['replaceHTML', 'build']);

使用Browserify完整版如下:

//Tyler using browserify

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var htmlreplace = require('gulp-html-replace');;
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify');
var streamify = require('gulp-streamify');

var path = {
    HTML: 'Tyler/src/index.html'
    , MINIFIED_OUT: 'build.min.js'
    , OUT: 'build.js'
    , DEST: 'Tyler/dist1'
    , DEST_BUILD: 'Tyler/dist1/build'
    , DEST_SRC: 'Tyler/dist1/src'
    , ENTRY_POINT: 'Tyler/src/js/App.js'
};

//Tyler/src/index.html&#x4E2D;&#x590D;&#x5236;&#x5230;TylerTyler/dist&#x4E2D;
gulp.task('copy', function () {
    gulp.src(path.HTML)
        .pipe(gulp.dest(path.DEST));
});

//&#x76D1;&#x6D4B;
gulp.task('watch', function () {

    //&#x76D1;&#x6D4B;html&#x6587;&#x4EF6;
    gulp.watch(path.HTML, ['copy']);

    //watchify&#x914D;&#x5408;browserify&#x4F7F;&#x7528;&#xFF0C;&#x56E0;&#x4E3A;&#x5355;&#x72EC;&#x4F7F;&#x7528;browserify&#x4F1A;&#x6BCF;&#x6B21;&#x904D;&#x5386;&#x6BCF;&#x4E2A;&#x7EC4;&#x4EF6;&#xFF0C;&#x4E00;&#x65E6;&#x6709;&#x53D8;&#x5316;&#x5C31;&#x4F1A;&#x91CD;&#x65B0;&#x751F;&#x6210;&#x7ED1;&#x5B9A;&#x6587;&#x4EF6;&#x3002;&#x800C;&#x6709;&#x4E86;watchify&#xFF0C;&#x4F1A;&#x7F13;&#x5B58;&#x6587;&#x4EF6;&#xFF0C;&#x53EA;&#x66F4;&#x65B0;&#x54EA;&#x4E9B;&#x53D1;&#x751F;&#x6539;&#x53D8;&#x7684;&#x6587;&#x4EF6;
    var watcher = watchify(browserify({
        entries: [path.ENTRY_POINT], //Tyler/src/js/App.js, browserify&#x4F1A;&#x68C0;&#x6D4B;Tyler/src/js&#x4E0B;&#x7684;&#x6240;&#x6709;js&#x6587;&#x4EF6;&#xFF0C;&#x4EE5;&#x53CA;Tyler/src/js&#x4E0B;&#x6240;&#x6709;&#x5B50;&#x6587;&#x4EF6;&#x5939;&#x4E0B;&#x7684;js&#x6587;&#x4EF6;
        transform: [reactify], //&#x4F7F;&#x7528;reactify&#x628A;jsx&#x8F6C;&#x6362;&#x6210;js&#x6587;&#x4EF6;
        debug: true, //&#x544A;&#x8BC9;Browersify&#x4F7F;&#x7528;source maps, souce maps&#x5E2E;&#x52A9;&#x6211;&#x4EEC;&#x5728;&#x51FA;&#x73B0;&#x9519;&#x8BEF;&#x7684;&#x65F6;&#x5019;&#x5B9A;&#x4F4D;&#x5230;jsx&#x4E2D;&#x7684;&#x9519;&#x8BEF;&#x884C;
        cache: {}, //&#x5FC5;&#x987B;&#x7684;&#xFF0C;browserify&#x544A;&#x8BC9;&#x6211;&#x4EEC;&#x8FD9;&#x6837;&#x4F7F;&#x7528;
        packageCache: {}, //&#x5FC5;&#x987B;&#x7684;&#xFF0C;browserify&#x544A;&#x8BC9;&#x6211;&#x4EEC;&#x8FD9;&#x6837;&#x4F7F;&#x7528;
        fullPath: true //&#x5FC5;&#x987B;&#x7684;&#xFF0C;browserify&#x544A;&#x8BC9;&#x6211;&#x4EEC;&#x8FD9;&#x6837;&#x4F7F;&#x7528;
    }));

    return watcher.on('update', function () {
            watcher.bundle() //&#x628A;&#x6240;&#x6709;&#x7684;jsx&#x6587;&#x4EF6;&#x7ED1;&#x5B9A;&#x5230;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;
                .pipe(source(path.OUT))
                .pipe(gulp.dest(path.DEST_SRC));

            console.log('Updated');
        })
        .bundle()
        .pipe(source(path.OUT))
        .pipe(gulp.dest(path.DEST_SRC));

});

//&#x9ED8;&#x8BA4;&#x7684;task
gulp.task('default', ['watch']);

//&#x53D1;&#x5E03;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E4B;&#x524D;
gulp.task('build', function () {
            browserify({
                    entries: [path.ENTRY_POINT]
                    , transform: [reactify]
                })
                .bundle()
                .pipe(source(path.MINIFIED_OUT))
                    .pipe(streamify(uglify(path.MINIFIED_OUT)))
                    .pipe(gulp.dest(path.DEST_BUILD));
                });

gulp.task('replaceHTML', function () {
    gulp.src(path.HTML)
        .pipe(htmlreplace({
            'js': 'build/' + path.MINIFIED_OUT
        }))
        .pipe(gulp.dest(path.DEST));
});

gulp.task('production', ['replaceHTML', 'build']);

Original: https://www.cnblogs.com/darrenji/p/5505499.html
Author: Darren Ji
Title: 使用Gulp和Browserify来搭建React应用程序

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/551551/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Hello World

    写Hello World的步骤 新建文件夹存放代码 新建一个java文件 文件后缀名为.java Hello.java 【注意】系统可能没有显示后缀名,需要手动打开(如果没有Win…

    技术杂谈 2023年6月21日
    093
  • MySQL建表语句生成Golang代码

    1. 背景 对于后台开发新的需求时,一般会先进行各种表的设计,写各个表的建表语句 然后根据建立的表,写对应的model代码、基础的增删改查代码(基础的增删改查服务可以划入DAO(D…

    技术杂谈 2023年6月21日
    0117
  • 在OAuth2.0模式下使用SpringCloudGateway

    Spring Cloud Gateway主要用于以下角色之一: OAuth Client *OAuth Resource Server 1 Spring Cloud Gateway…

    技术杂谈 2023年7月23日
    094
  • 7-8月全球技术标准更新

    1.巴西 ANATEL 就有线充电接口USB Type-C 标准开展公众咨询 巴西ANATEL 已启动第45 号公众咨询,该提案定义了强制性技术要求,以评估手机中有线充电接口与US…

    技术杂谈 2023年6月21日
    064
  • Golang仿云盘项目-3.2云存储系统之持久化

    本文来自博客园,作者:Arway,转载请注明原文链接:https://www.cnblogs.com/cenjw/p/16478717.html 项目结构 . ├── db │ ├…

    技术杂谈 2023年7月24日
    075
  • 面向对象ooDay5

    默认的:什么也不写,本类、同包类 说明: java不建议默认访问权限 类的访问权限只能是public或默认的,类中成员的访问权限如上4种都可以 访问权限由小到大依次为:privat…

    技术杂谈 2023年7月11日
    080
  • IDEA一键部署SpringBoot项目到服务器

    1. 安装Alibaba Cloud Toolkit插件 2. 配置部署环境 2.1 为本次部署设置一个名字 2.2 选择被部署文件的生成方式 IDEA提供了三种方式: Maven…

    技术杂谈 2023年7月24日
    075
  • Docker容器网络

    Docker容器网络 1、Docker容器网络 Docker在安装后自动提供3种网络,可以使用`docker network ls命令查看 [root@localhost ~]# …

    技术杂谈 2023年6月21日
    0108
  • PHP实现Modbus RTU CRC16校验

    <?php // input-> modbus rtu string // output -> 2bytes string, in correct modbus …

    技术杂谈 2023年5月31日
    087
  • 原型模式详解

    原型模式 1.1原型模式概述 1.1.1原型模式定义 原型模式(Prototype Pattern)指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象,属于创建型设计模…

    技术杂谈 2023年6月21日
    0106
  • 低代码如何构建支持OAuth2.0的后端Web API

    OAuth2.0 OAuth 是一个安全协议,用于保护全球范围内大量且不断增长的Web API。它用于连接不同的网站,还支持原生应用和移动应用于云服务之间的连接,同时它也是各个领域…

    技术杂谈 2023年5月31日
    093
  • 快速应用程序开发

    什么是 RAD ? 快速应用程序开发(RAD)是一种专注于设计和原型设计阶段的开发方法,目的是获得用户的即时反馈。与先进行初始计划再进一步执行的传统开发模型不同,RAD 有着更多的…

    技术杂谈 2023年6月21日
    0116
  • DeepHyperX代码理解-HamidaEtAl

    代码复现自论文《3-D Deep Learning Approach for Remote Sensing Image Classification》 先对部分基础知识做一些整理:…

    技术杂谈 2023年6月21日
    091
  • 我的极客时间专栏结课了!!!

    我的极客时间专栏结课了!!! 我的极客时间专栏结课了!!!太TMD不容易了。 今天下班到家的时候,收到了一份包裹,里面是极客时间送的结课礼物。是的,我的《手把手带你写一个web框架…

    技术杂谈 2023年6月1日
    082
  • React-native 导航插件React Navigation 4.x的使用

    文档 英文水平可以的话,建议直接阅读英文文档 简单使用介绍 安装插件 yarn add react-navigation react-native-reanimated react…

    技术杂谈 2023年5月31日
    079
  • 渐进式web应用开发—Service Worker 与页面通信(七)

    回到顶部 一:页面窗口向 service worker 通信 Service Worker 没有直接操作页面DOM的权限。但是可以通过postMessage方法和web页面进行通信…

    技术杂谈 2023年6月1日
    083
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球