ビルドツールGulpの詳細な紹介

零下一度
リリース: 2017-06-26 11:21:18
オリジナル
1502 人が閲覧しました

前の言葉

grunt と同様、gulp もビルド ツールですが、grunt の頻繁な IO 操作と比較して、gulp のストリーム操作はビルド作業をより速く、より便利に完了できます。 Gulp は Unix オペレーティング システムのパイプのアイデアを利用しており、前のレベルの出力が次のレベルの入力になるため、操作が非常に簡単になります。この記事では、Gulp を使用して開発プロセスを変更し、開発をより迅速かつ効率的に行う方法を学びます。主に以下の手順になります

1. gulpをグローバルにインストール

$ npm install --global gulp
ログイン後にコピー

2. プロジェクトの開発依存関係(devDependency)として

$ npm install --save-dev gulp
ログイン後にコピー

をインストールする 3. プロジェクトルートにgulpfile.js

file:

var gulp = require('gulp');

gulp.task('default', function() {  // 将你的默认的任务代码放在这});
ログイン後にコピー
gulpfile.js 的文件:
$ gulp
ログイン後にコピー

  4. 运行 gulp:

“src/a.js”:指定具体文件;
“*”:匹配所有文件 例:src/*.js(包含src下的所有js文件);
“**”:匹配0个或多个子文件夹 例:src/**/*.js(包含src的0个或多个子文件夹下的js文件);
“{}”:匹配多个属性 例:src/{a,b}.js(包含a.js和b.js文件)src/*.{jpg,png,gif}(src中所有jpg/png/gif文件)
“!”:排除文件 例:!src/a.js(不包含src下的a.js文件);
ログイン後にコピー

  默认的名为 default 的任务(task)将会被运行,在这里,这个任务并未做任何事情。

  想要单独执行特定的任务(task),请输入 gulp <task> <othertask> 4. gulp を実行します:

var gulp = require('gulp'),
    less = require('gulp-less');
 
gulp.task('testLess', function () {//gulp.src('less/test/style.less')gulp.src(['less/**/*.less','!less/{extend,page}/*.less'])
        .pipe(less())
        .pipe(gulp.dest('./css'));
});
ログイン後にコピー

デフォルトのタスクの名前は、default (タスク) になります。ここでは、このタスクは何も行いません。

特定のタスクを単独で実行したい場合は、gulp <task><othertask>と入力してください

API

gulpの構成を学ぶ前に、まず、 gulp API

【gulp.src(globs[, options])】
の関与 処理が必要なソースファイルのパスを指定し、現在のファイルストリームを利用可能なプラグインに返します。パラメータは次のとおりです。 follow
globs: 処理する必要があるソース ファイル マッチャーのパス。タイプ (必須): String または StringArray;

ワイルドカード パスの一致例:
options.buffer:类型:Boolean 默认true,设为false将返回file.content的流且不缓冲文件,处理大文件时有用
options.read: 类型:Boolean 默认:true 设置false,将不执行读取文件操作,返回null;
options.base: 类型:String 设置输出路径以某个路径的某个组成部分为基础向后拼接
ログイン後にコピー
gulp.src('client/js/**/*.js')//匹配'client/js/somedir/somefile.js'且将`base`解析为`client/js/`  .pipe(minify())
  .pipe(gulp.dest('build'));  // 写入 'build/somedir/somefile.js'gulp.src('client/js/**/*.js', { base: 'client' })
  .pipe(minify())
  .pipe(gulp.dest('build'));  // 写入 'build/js/somedir/somefile.js'
ログイン後にコピー

オプション: タイプ (オプション): 3 つの属性を持つオブジェクト、

gulp.src('./client/templates/*.jade')
  .pipe(jade())
  .pipe(gulp.dest('./build/templates'))
  .pipe(minify())
  .pipe(gulp.dest('./build/minified_templates'));
ログイン後にコピー

path:  类型(必填):String or Function 指定文件输出路径,或者定义函数返回文件输出路径亦可
options:  类型(可选):Object,有2个属性cwd、mode;
    options.cwd:类型:String 默认:process.cwd():前脚本的工作目录路径 文件输出路径为相对路径会用到
    options.mode:类型:String 默认:0777 指定被创建文件夹的权限
ログイン後にコピー
【gulp.dest(path[, options])】

処理後に出力されるファイルのパスを指定します。複数のフォルダーにパイプすることができます。フォルダーが存在しない場合は、自動的に作成されます
[注意] ファイルが書き込まれるパスは、指定された相対パスと指定されたターゲット ディレクトリに基づいて計算されます。同様に、相対パスも与えられたbaseに基づいて計算できます

name:  类型(必填):String 指定任务的名称(不应该有空格);
deps:  类型(可选):StringArray,该任务依赖的任务列表
fn:    类型(必填):Function 该任务调用的插件操作
ログイン後にコピー

このメソッドのパラメータは以下の通りです
var gulp = require('gulp');// 返回一个 callback,因此系统可以知道它什么时候完成gulp.task('one', function(cb) {// 做一些事 -- 异步的或者其他的cb(err); // 如果 err 不是 null 或 undefined,则会停止执行,且注意,这样代表执行失败了});// 定义一个所依赖的 task 必须在这个 task 执行之前完成gulp.task('two', ['one'], function() {// 'one' 完成后});
gulp.task('default', ['one', 'two']);
ログイン後にコピー

【gulp.task(name[, deps], fn)】

Define a gulp タスク、パラメーターは次のとおりです

gulp.task('testLess', function () {return gulp.src(['less/style.less'])
        .pipe(less())
        .pipe(gulp.dest('./css'));
});
 
gulp.task('minicss', ['testLess'], function () { //执行完testLess任务后再执行minicss任务gulp.src(['css/*.css'])
        .pipe(minifyCss())
        .pipe(gulp.dest('./dist/css'));
});
ログイン後にコピー

デフォルトでは、タスクは最大同時実行数で実行されます。つまり、gulp は待機せずにすべてのタスクを一度に実行します。シリアル化されたタスク キューを作成し、特定の順序で実行したい場合は、次の 2 つのことを行う必要があります。 1. タスクが実行されたことを知らせるプロンプトを表示します。 2. タスクが実行されたことを知らせる別のプロンプトを表示します。別のタスクの完了。
この例では、「one」と「two」という 2 つのタスクがあり、次の順序で実行したいとします。
「one」には、いつ完了するかを示すヒントを追加します: OK When完了した場合、コールバックを返すか、Promise またはストリームを返して、システムが完了するまで待機します。

「2」では、完了するには最初のタスクに依存する必要があることをシステムに伝えるヒントを追加する必要があります

  event.path:    类型:String  触发了该事件的文件的路径
ログイン後にコピー

gulp.task('watch1', function () {
    gulp.watch('less/**/*.less', ['testLess']);
});
ログイン後にコピー
【gulp.watch(glob [, opts], tables)]
【gulp. watch(glob [, opts, cb])】
watchメソッドはファイルが変更されると、指定されたタスクが実行されます
gulp.watch('js/**/*.js', function(event) {
  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
ログイン後にコピー

var watcher = gulp.watch('js/**/*.js', ['uglify','reload']);
watcher.on('change', function(event) {
  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
ログイン後にコピー

-v 或 --version         会显示全局和项目本地所安装的gulp版本号--require <module path>     将会在执行之前reqiure一个模块。可以使用多个--require--gulpfile <gulpfile path>   手动指定一个gulpfil 的路径,会将CWD设置到该gulpfile所在目录--cwd <dir path>         手动指定CWD。定义gulpfile查找的位置,所有的相应依赖会从这里开始计算相对路径-T 或 --tasks           会显示所指定 gulpfile 的 task 依赖树--tasks-simple          会以纯文本的方式显示所载入的 gulpfile 中的 task 列表--color              强制 gulp 和 gulp 插件显示颜色,即便没有颜色支持--no-color            强制不显示颜色,即便检测到有颜色支持--silent              禁止所有的 gulp 日志
ログイン後にコピー

var gulp = require('gulp'),
    concat = require('gulp-concat');
 
gulp.task('testConcat', function () {
    gulp.src('src/js/*.js')
        .pipe(concat('all.js'))//合并后的文件名.pipe(gulp.dest('dist/js'));
});
ログイン後にコピー

コマンドライン

【パラメータマーク】

var gulp = require('gulp'),
    uglify= require('gulp-uglify');
 
gulp.task('jsmin', function () {//压缩src/js目录下的所有js文件//除了test1.js和test2.js(**匹配src/js的0个或多个子文件夹)gulp.src(['src/js/*.js', '!src/js/**/{test1,test2}.js']) 
        .pipe(uglify())
        .pipe(gulp.dest('dist/js'));
});
ログイン後にコピー

コマンドラインは process.env.INIT_CW のどこから実行されたかを記録します

【タスク】

タスク缶gulp を介して実行されます。 gulp コマンドのみを実行すると、default という名前で登録されたタスクが実行されます。そのようなタスクが存在しない場合、gulp はエラーを報告します。ファイル

var gulp = require('gulp'),
    requirejs = require('gulp-requirejs');

gulp.task('script',function(){//将js模块打包成一个文件return requirejs({
          baseUrl: 'src/js',
          paths:{'jquery':'../../dist/js/jquery'  },
          out:'main.js',
          name: 'main',       
          exclude: ['jquery']
    })
    .pipe(gulp.dest('dist/js')); 
})
ログイン後にコピー

【jshint】jsコード検出
 gulp = require('gulp'= require('gulp-jshint''script','src/js/*.js'.pipe(jshint('.jshintrc'.pipe(jshint.reporter('default'
ログイン後にコピー

2. CSS関連プラグイン

【clean -css】 CSSファイルを圧縮します
var gulp = require('gulp');var cleanCSS = require('gulp-clean-css');
 
gulp.task('css', function() {
  gulp.src('src/css/*.css')
        .pipe(cleanCSS({compatibility: 'ie8'}))
        .pipe(gulp.dest('dist/css'));
});
ログイン後にコピー

【sass】将scss文件编译成css

  gulp-sass的安装并不是一个简单的事

  1、如果gulp-sass安装不成功,可能出现以下提示

Cannot download https://github.com/sass/node-sass/releases/download/v3.4.2/win32-x64-46_binding.node
ログイン後にコピー

  这是因为gulp-sass依赖于node-sass,而由于网络原因,node-sass的服务器无法访问,可以有如下解决方法

  先使用淘宝的镜像安装node-sass

npm install  node-sass --sass-binary-site= http://n pm.taobao.org/mirrors/node-sass/
ログイン後にコピー

  再安装gulp-sass

npm install gulp-sass
ログイン後にコピー

  2、安装成功后,也可能无法正确使用。在使用sass编译css文件时,可能会出现' %1 is not a valid win32 application'这样的错误,这是因为gulp-sass依赖于node-sass,而node-sass版本太高,可以安装3.*.*版本,此时,依然要使用淘宝cnpm进行镜像安装

cnpm install node-sass@3.11.0
ログイン後にコピー
var gulp = require('gulp'),
    sass = require('gulp-sass');

gulp.task('sass',function(){
  gulp.src('src/sass/*.scss')
      .pipe(sass().on('error', sass.logError))
      .pipe(gulp.dest('dist/css')); 
});
ログイン後にコピー

【autoprefixer】根据设置浏览器版本自动处理浏览器前缀

var gulp = require('gulp'),
    autoprefixer = require('gulp-autoprefixer');

gulp.task('css',function(){
  gulp.src('src/css/*.css')
        .pipe(autoprefixer({
            browsers: ['last 2 versions', 'Android >= 4.0'],
            cascade: true, //是否美化属性值 默认:true 像这样://-webkit-transform: rotate(45deg);//        transform: rotate(45deg);remove:true //是否去掉不必要的前缀 默认:true         }))
        .pipe(gulp.dest('dist/css'))
});
ログイン後にコピー

  gulp-autoprefixer的browsers参数详解

last 2 versions: 主流浏览器的最新两个版本
last 1 Chrome versions: 谷歌浏览器的最新版本
last 2 Explorer versions: IE的最新两个版本
last 3 Safari versions: 苹果浏览器最新三个版本
Firefox >= 20: 火狐浏览器的版本大于或等于20
iOS 7: IOS7版本
Firefox ESR: 最新ESR版本的火狐> 5%: 全球统计有超过5%的使用率
ログイン後にコピー

【csslint】检测CSS代码

var gulp = require('gulp'),
    csslint = require('gulp-csslint');

gulp.task('css',function(){
    gulp.src('src/css/*.css')//设置css检测规则,并检测css代码.pipe(csslint('.csslintrc'))//对代码进行报错提示    .pipe(csslint.formatter())
});
ログイン後にコピー

【concat】合并文件

var gulp = require('gulp');var concat = require('gulp-concat');
 
gulp.task('css', function() {
    gulp.src('src/css/*.css')
        .pipe(concat('all.css'))
        .pipe(gulp.dest('dist/css'));
});
ログイン後にコピー

3、HTML相关插件

【htmlmin】压缩html

var gulp = require('gulp');var htmlmin = require('gulp-htmlmin');
 
gulp.task('html', function() {
    gulp.src('*.html')
        .pipe(htmlmin({collapseWhitespace: true}))
        .pipe(gulp.dest('dist/html'));
});
ログイン後にコピー
var gulp = require('gulp'),
    htmlmin = require('gulp-htmlmin');
 
gulp.task('testHtmlmin', function () {var options = {
        removeComments: true,//清除HTML注释collapseWhitespace: true,//压缩HTMLcollapseBooleanAttributes: true,//省略布尔属性的值 <input checked="true"/> ==> <input />removeEmptyAttributes: true,//删除所有空格作属性值 <input id="" /> ==> <input />removeScriptTypeAttributes: true,//删除<script>的type="text/javascript"removeStyleLinkTypeAttributes: true,//删除<style>和<link>的type="text/css"minifyJS: true,//压缩页面JSminifyCSS: true//压缩页面CSS    };
    gulp.src('src/html/*.html')
        .pipe(htmlmin(options))
        .pipe(gulp.dest('dist/html'));
});
ログイン後にコピー

4、图片相关插件

【imagemin】压缩图片文件

var gulp = require('gulp'),
    imagemin = require('gulp-imagemin');
 
gulp.task('testImagemin', function () {
    gulp.src('src/img/*.{png,jpg,gif,ico}')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/img'));
});
ログイン後にコピー
var gulp = require('gulp'),
    imagemin = require('gulp-imagemin');
 
gulp.task('testImagemin', function () {
    gulp.src('src/img/*')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/img'));
});
ログイン後にコピー

【spritesmith】制作雪碧图

  [注意]该插件与别的插件有所不同,它的使用方式是gulp.spritesmith,而不是gulp-spritesmith

var gulp = require('gulp');var spritesmith = require('gulp.spritesmith');
 
gulp.task('img', function() {return gulp.src('src/img/*')
        .pipe(spritesmith({'imgName':'sprite.png','cssName':'sprite.css','padding':5 //合并时两张图片的距离        }))
        .pipe(gulp.dest('dist/img'));
});
ログイン後にコピー

5、文件相关插件

【rename】重命名

var gulp = require('gulp');var rename = require('gulp-rename');
 
gulp.task('file', function() {
    gulp.src('src/css/all.css')
        .pipe(rename('a.css'))
        .pipe(gulp.dest('dist/css'));
});
ログイン後にコピー
var gulp = require('gulp');var rename = require('gulp-rename');
 
gulp.task('file', function() {
    gulp.src('src/css/all.css')
        .pipe(rename(function(path){
            path.basename += "-min";
            path.extname = ".scss"}))
        .pipe(gulp.dest('dist/css'));
});
ログイン後にコピー

【clean】删除文件

var gulp = require('gulp');var clean = require('gulp-clean');

gulp.task('clean', function () {return gulp.src('dist/img/*')
        .pipe(clean());
});
ログイン後にコピー

  [注意]由于gulp中的任务是同步的,如果并列写,完全可能出现边编译边删除的情况

gulp.task('default', ['clean', 'less', 'images', 'js', 'watch']);//错误
ログイン後にコピー

  所以需要配置一个异步,非常简单,加个回调

//正确gulp.task('default', ['clean'], function(){
    gulp.start('less', 'images', 'js', 'watch');
});
ログイン後にコピー

【zip】将文件变成zip压缩文件

  [注意]如果gulp.src()的路径设置为'dist/*',则压缩包只包含dist空文件夹,而不包含实际内容

var gulp = require('gulp');var zip = require('gulp-zip');
 
gulp.task('file', function() {
    gulp.src('dist/**/*')
        .pipe(zip('project.zip'))
        .pipe(gulp.dest('out'));
});
ログイン後にコピー

6、Hash相关插件

【useref】解析构建块在HTML文件来代替引用未经优化的脚本和样式表

//index.html<!-- build:css /css/all.css -->
<link rel="stylesheet" href="src/css/style1.css?1.1.11">
<!-- endbuild -->
ログイン後にコピー
ログイン後にコピー
var gulp = require('gulp');var useref = require('gulp-useref');
 
gulp.task('file', function() {
    gulp.src('*.html')
        .pipe(useref())
        .pipe(gulp.dest('dist'));
});
ログイン後にコピー
//dist/index.html<link rel="stylesheet" href="/css/all.css?1.1.11">
ログイン後にコピー

【rev】给文件名添加hash值

 gulp = require('gulp' rev = require('gulp-rev''file', '*.html''dist'
ログイン後にコピー

【rev-repalce】重写被gulp-rev重命名的文件名

//index.html<!-- build:css /css/all.css -->
<link rel="stylesheet" href="src/css/style1.css?1.1.11">
<!-- endbuild -->
ログイン後にコピー
ログイン後にコピー
var gulp = require('gulp');var rev = require('gulp-rev');var useref = require('gulp-useref');var revReplace = require('gulp-rev-replace');
 
gulp.task('file', function() {
    gulp.src('*.html')
        .pipe(useref())
        .pipe(rev())
        .pipe(revReplace())
        .pipe(gulp.dest('dist'));
});
ログイン後にコピー
//index-bc596e88c8.html<link rel="stylesheet" href="/css/all-ef5462562d.css?1.1.11">
ログイン後にコピー

7、其他插件

【connect】生成一个服务器

var gulp = require('gulp');var connect = require('gulp-connect');

gulp.task('connect', function() {
    connect.server();
});
ログイン後にコピー

【babel】将ES6代码编译成ES5

var gulp = require('gulp');var babel = require('gulp-babel');
 
gulp.task('es6', function(){return gulp.src('src/js/*.js')
        .pipe(babel({
            presets: ['es2015']
        }))
        .pipe(gulp.dest('dist/js'));
});
ログイン後にコピー

 

配置

  在实际开发中,并不会直接使用原生javascript进行开发,使用库或框架开发会更高效,以requiejs和jquery的配置为例。项目目录结构如下

【img】

  将'src/img'中的普通图片压缩保存到'dist/img'中,将'src/img/sprite'中的图片制作雪碧图

 gulp = require('gulp' imagemin = require('gulp-imagemin' spritesmith = require('gulp.spritesmith''img', gulp.src('src/img/*.{png,jpg,gif,ico}''dist/img' gulp.src('src/img/sprite/*''imgName':'sprite.png''cssName':'sprite.css''padding':5'src/css/temp''default',['img']);
ログイン後にコピー

【css】

  css部分由sass编译成对应的css存储在'src/css'中,然后,对css文件进行检测、合并、自动添加前缀、压缩后,存储在'dist/css'中

var gulp = require('gulp');var concat = require('gulp-concat');var csslint = require('gulp-csslint');var sass = require('gulp-sass');var autoprefixer = require('gulp-autoprefixer');var cleancss = require('gulp-clean-css');var concat = require('gulp-concat');

gulp.task('css', function() {
  gulp.src('src/css/sass/*.scss')//将sass编译为css代码  .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest('src/css/temp'));     gulp.src('src/css/temp/*.css')//设置css检测规则,并检测css代码.pipe(csslint('.csslintrc'))//对代码进行报错提示        .pipe(csslint.formatter())//合并文件.pipe(concat('style.css'))//根据设置浏览器版本自动处理浏览器前缀        .pipe(autoprefixer({
            browsers: ['last 2 versions', 'Android >= 4.0']
        }))       //压缩css文件.pipe(cleancss({compatibility: 'ie8'}))//输出到目标目录.pipe(gulp.dest('dist/css'));
       
});
gulp.task('default',['sass','css']);
ログイン後にコピー

【js】

  js部分由gulp-requirejs打包为'main.js'之后,进行压缩,最后存储在'dist/js'中,所依赖的框架requirejs和jquery不打包,直接存储在'dist/js'中

var gulp = require('gulp');var requirejs = require('gulp-requirejs');var uglify = require('gulp-uglify');

gulp.task('js', function() {//将js模块打包成一个文件return requirejs({
          baseUrl: 'src/js',
          paths:{'jquery':'../../dist/js/jquery'  },
          out:'main.js',
          name: 'main',       
          exclude: ['jquery']
    })//压缩文件    .pipe(uglify())
    .pipe(gulp.dest('dist/js'));
});

gulp.task('default',['js']);
ログイン後にコピー

【版本号】

  为文件设置版本号

<!-- build:css dist/css/style.css -->
<link rel="stylesheet" href="dist/css/style.css?1.1.11">
<!-- endbuild -->
ログイン後にコピー
var gulp = require('gulp');var rev = require('gulp-rev');var useref = require('gulp-useref');var revReplace = require('gulp-rev-replace');
 
gulp.task('file', function() {
    gulp.src('*.html')
        .pipe(useref())
        .pipe(rev())
        .pipe(revReplace())
        .pipe(gulp.dest(''));
});
gulp.task('default',['file']);
ログイン後にコピー
<link rel="stylesheet" href="dist/css/style-0f788265cc.css?1.1.11">
ログイン後にコピー

【监控】

/**image**/var gulp = require('gulp');var imagemin = require('gulp-imagemin');var spritesmith = require('gulp.spritesmith'); 

gulp.task('img', function () {//压缩图片gulp.src('src/img/*.{png,jpg,gif,ico}')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/img'));//制作雪碧图gulp.src('src/img/sprite/*')
        .pipe(spritesmith({'imgName':'sprite.png','cssName':'sprite.css','padding':5 
        }))
        .pipe(gulp.dest('src/css/temp'));
  gulp.src('src/css/temp/sprite.png')
        .pipe(gulp.dest('dist/img'));
});/**css**/var concat = require('gulp-concat');var csslint = require('gulp-csslint');var sass = require('gulp-sass');var autoprefixer = require('gulp-autoprefixer');var cleancss = require('gulp-clean-css');var concat = require('gulp-concat');

gulp.task('css', function() {
  gulp.src('src/css/sass/*.scss')//将sass编译为css代码  .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest('src/css/temp'));/*});
gulp.task('css', function() {  */             
  gulp.src('src/css/temp/*.css')//设置css检测规则,并检测css代码   // .pipe(csslint('.csslintrc'))//对代码进行报错提示   // .pipe(csslint.formatter())//合并文件.pipe(concat('style.css'))//根据设置浏览器版本自动处理浏览器前缀        .pipe(autoprefixer({
            browsers: ['last 2 versions', 'Android >= 4.0']
        }))       //压缩css文件.pipe(cleancss({compatibility: 'ie8'}))//输出到目标目录.pipe(gulp.dest('dist/css'));
       
});/**js**/var requirejs = require('gulp-requirejs');var uglify = require('gulp-uglify');

gulp.task('js', function() {//将js模块打包成一个文件return requirejs({
          baseUrl: 'src/js',
          paths:{'jquery':'../../dist/js/jquery'  },
          out:'main.js',
          name: 'main',       
          exclude: ['jquery']
    })//压缩文件    .pipe(uglify())
    .pipe(gulp.dest('dist/js'));
});/**版本号**/var rev = require('gulp-rev');var useref = require('gulp-useref');var revReplace = require('gulp-rev-replace');
 
gulp.task('file',['css'],function() {
    gulp.src('*.html')
        .pipe(useref())
        .pipe(rev())
        .pipe(revReplace())
        .pipe(gulp.dest('dist/'));
});/**监控**/gulp.task('auto',function(){
    gulp.watch('src/img',['img']);
    gulp.watch('src/css/**/*',['css']);
    gulp.watch('src/js**/*',['js']);
    gulp.watch('dist/css/*.css',['file']);
})

gulp.task('default',['js','img','css','file','auto']);
ログイン後にコピー

 

  

以上がビルドツールGulpの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート