一、安装webpack

  • 需要先在项目中npm init初始化一下,生成package.json
  • 建议node版本安装到8.2以上
  1. // webpack4中除了正常安装webpack之外,需要再单独安一个webpack-cli
  2.  
  3. npm i webpack webpack-cli -D

  ★ npm i -D 是 npm install --save-dev 的简写,是指安装模块并保存到 package.json 的 devDependencies中,主要在开发环境中的依赖包

0配置了什么

webpack4可以支持0配置打包,这里所说的0配置又是什么呢?当然在开发者眼中0配置的东西,那根本是无法用的,因为不够智能,那么我们就来看看做到了哪些0配置

在使用webpack进行打包的时候,默认情况下会将src下的入口文件(index.js)进行打包

  1. // node v8.2版本以后都会有一个npx
  2. // npx会执行bin里的文件
  3.  
  4. npx webpack // 不设置mode的情况下 打包出来的文件自动压缩
  5.  
  6. npx webpack --mode development // 设置mode为开发模式,打包后的文件不被压缩

当执行npx webpack命令的时候,webpack会自动查找项目中src目录下的index.js文件,然后进行打包,生成一个dist目录并存在一个打包好的main.js文件

这些算是0配置的操作了,名字都是定义好的

webpack是基于Node的

在项目下创建一个webpack.config.js(默认,可修改)文件来配置webpack

  1. module.exports = {
  2. entry: '', // 入口文件
  3. output: {}, // 出口文件
  4. module: {}, // 处理对应模块
  5. plugins: [], // 对应的插件
  6. devServer: {}, // 开发服务器配置
  7. mode: 'development' // 模式配置
  8. }

  

以上就是webpack的正常配置模块

★ 启动devServer需要安装一下webpack-dev-server

  1. npm i webpack-dev-server -D

按照项目的结构,我们就从0开始去写一下配置吧

  1. // webpack.config.js
  2.  
  3. const path = require('path');
  4.  
  5. module.exports = {
  6. entry: './src/index.js', // 入口文件
  7. output: {
  8. filename: 'bundle.js', // 打包后的文件名称
  9. path: path.resolve('dist') // 打包后的目录,必须是绝对路径
  10. }
  11. }

 上面就可以说是实现了最简单的webpack配置了,那接下来就打包一下看看

配置执行文件

工作当中我们打包编译的时候一般都执行npm run dev这样的命令,既然是通过npm执行的命令,我们就应该找到package.json里的执行脚本去配置一下命令,这里如下图所示

npm run build就是我们打包后的文件,这是生产环境下,上线需要的文件

npm run dev是我们开发环境下打包的文件,当然由于devServer帮我们把文件放到内存中了,所以并不会输出打包后的dist文件夹

通过npm run build之后会生成一个dist目录文件夹,就和上面打包后的样子一样了

多入口文件

多个入口可以有两种实现方式进行打包

  • 一种是没有关系的但是要打包到一起去的,可以写一个数组,实现多个文件打包
  • 另一种就是每一个文件都单独打包成一个文件的
  • 下面就来看看这两种方式的写法
  1. let path = require('path');
  2.  
  3. module.exports = {
  4. // 1.写成数组的方式就可以打出多入口文件,不过这里打包后的文件都合成了一个
  5. // entry: ['./src/index.js', './src/login.js'],
  6. // 2.真正实现多入口和多出口需要写成对象的方式
  7. entry: {
  8. index: './src/index.js',
  9. login: './src/login.js'
  10. },
  11. output: {
  12. // 1. filename: 'bundle.js',
  13. // 2. [name]就可以将出口文件名和入口文件名一一对应
  14. filename: '[name].js', // 打包后会生成index.js和login.js文件
  15. path: path.resolve('dist')
  16. }
  17. }

  

这时候执行npm run build后,会生成打包好的两个js文件,如图所示

配置Html模板

文件都打包好了,但是我们在使用的时候不能在dist目录下去创建一个html文件,然后去引用打包后的js吧,这不合理,实际开发中也不会这样

我们需要实现html打包功能,可以通过一个模板实现打包出引用好路径的html来

这就需要用到一个常用的插件了,html-webpack-plugin,用之前我们来安一下它

  1. npm i html-webpack-plugin -D

 

因为是个插件,所以需要在config.js里引用一下的

  1. let path = require('path');
  2. // 插件都是一个类,所以我们命名的时候尽量用大写开头
  3. let HtmlWebpackPlugin = require('html-webpack-plugin');
  4.  
  5. module.exports = {
  6. entry: './src/index.js',
  7. output: {
  8. // 添加hash可以防止文件缓存,每次都会生成4位的hash串
  9. filename: 'bundle.[hash:4].js',
  10. path: path.resolve('dist')
  11. },
  12. plugins: [
  13. // 通过new一下这个类来使用插件
  14. new HtmlWebpackPlugin({
  15. // 用哪个html作为模板
  16. // 在src目录下创建一个index.html页面当做模板来用
  17. template: './src/index.html',
  18. hash: true, // 会在打包好的bundle.js后面加上hash串
  19. })
  20. ]
  21. }

  

通过上面的配置后,我们再npm run build打包看一下现在是个什么样子了

多页面开发,怎么配置多页面

如果开发的时候不只一个页面,我们需要配置多页面,那么需要怎么来搞呢?不用担心,html-webpack-plugin插件自有办法,我们来观望一下

  1. let path = require('path');
  2. let HtmlWebpackPlugin = require('html-webpack-plugin');
  3.  
  4. module.exports = {
  5. // 多页面开发,怎么配置多页面
  6. entry: {
  7. index: './src/index.js',
  8. login: './src/login.js'
  9. },
  10. // 出口文件
  11. output: {
  12. filename: '[name].js',
  13. path: path.resolve('dist')
  14. },
  15. plugins: [
  16. new HtmlWebpackPlugin({
  17. template: './src/index.html',
  18. filename: 'index.html',
  19. chunks: ['index'] // 对应关系,index.js对应的是index.html
  20. }),
  21. new HtmlWebpackPlugin({
  22. template: './src/login.html',
  23. filename: 'login.html',
  24. chunks: ['login'] // 对应关系,login.js对应的是login.html
  25. })
  26. ]
  27. }

  

继续npm run build看打包后的样子

上面基本介绍完了html和js的打包配置了,现在我们还缺一个好兄弟css,webpack对css的解析需要用到loader,所以我们先提前安装好,待会好方便使用

引用CSS文件

可以在src/index.js里引入css文件,到时候直接打包到生产目录下

需要下载一些解析css样式的loader

  1. npm i style-loader css-loader -D
  2. // 引入less文件的话,也需要安装对应的loader
  3. npm i less less-loader -D

  

下面我们来看一下如何配置css文件的解析

  1. // index.js
  2. import './css/style.css'; // 引入css
  3. import './less/style.less'; // 引入less
  4.  
  5. console.log('这里是打包文件入口-index.js');
  6.  
  7. // webpack.config.js
  8. module.exports = {
  9. entry: {
  10. index: './src/index.js'
  11. },
  12. output: {
  13. filename: 'bundle.js',
  14. path: path.resolve('dist')
  15. },
  16. module: {
  17. rules: [
  18. {
  19. test: /\.css$/, // 解析css
  20. use: ['style-loader', 'css-loader'] // 从右向左解析
  21. /*
  22. 也可以这样写,这种方式方便写一些配置参数
  23. use: [
  24. {loader: 'style-loader'},
  25. {loader: 'css-loader'}
  26. ]
  27. */
  28. }
  29. ]
  30. }
  31. }

  

  • 此时打包后的css文件是以行内样式style的标签写进打包后的html页面中,如果样式很多的话,我们更希望直接用link的方式引入进去,这时候需要把css拆分出来
  • extract-text-webpack-plugin插件相信用过的人都知道它是干什么的,它的功效就在于会将打包到js里的css文件进行一个拆分

拆分CSS

  1. // @next表示可以支持webpack4版本的插件
  2. npm i extract-text-webpack-plugin@next -D
  3. let path = require('path');
  4. let HtmlWebpackPlugin = require('html-webpack-plugin');
  5. // 拆分css样式的插件
  6. let ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
  7.  
  8. module.exports = {
  9. entry: './src/index.js',
  10. output: {
  11. filaneme: 'bundle.js',
  12. path: path.resolve('dist')
  13. },
  14. module: {
  15. rules: [
  16. {
  17. test: /\.css$/,
  18. use: ExtractTextWebpackPlugin.extract({
  19. // 将css用link的方式引入就不再需要style-loader了
  20. use: 'css-loader'
  21. })
  22. }
  23. ]
  24. },
  25. plugins: [
  26. new HtmlWebpackPlugin({
  27. template: './src/index.html',
  28. }),
  29. // 拆分后会把css文件放到dist目录下的css/style.css
  30. new ExtractTextWebpackPlugin('css/style.css')
  31. ]
  32. }

  

此时拆分完css后,打包的html页面就以link的方式去引入css了,这样很好

当然大家很多都说另外一个插件也是可以办到的,那就是mini-css-extract-plugin,是的可以说它是为webpack4而生的,而之所以上来就没有介绍是因为还不成熟,还有很多bug需要去解决的

不过既然大家都知道它,那就顺便也提一下吧

  1. npm i mini-css-extract-plugin -D

  

使用起来和上面的插件是差不多的

  1. let MiniCssExtractPlugin = require('mini-css-extract-plugin');
  2.  
  3. module.exports = {
  4. module: {
  5. rules: [
  6. {
  7. test: /\.css$/,
  8. use: [MiniCssExtractPlugin.loader, 'css-loader']
  9. }
  10. ]
  11. },
  12. plugins: [
  13. new MiniCssExtractPlugin({
  14. filename: 'css/a.css' // 指定打包后的css
  15. })
  16. ]
  17. }

  

拆分成多个css

这里要着重说一下上面两个插件的区别了,我个人还是建议用extract-text-webpack-plugin的,毕竟从之前的版本承接下来的,虽然在安包的时候需要@next,但是还是值得信赖的

而且现在的extract-text-webpack-plugin也支持了拆分成多个css,而目前mini-css-extract-plugin还不支持此功能

  1. // 正常写入的less
  2. let styleLess = new ExtractTextWebpackPlugin('css/style.css');
  3. // reset
  4. let resetCss = new ExtractTextWebpackPlugin('css/reset.css');
  5.  
  6. module.exports = {
  7. module: {
  8. rules: [
  9. {
  10. test: /\.css$/,
  11. use: resetCss.extract({
  12. use: 'css-loader'
  13. })
  14. },
  15. {
  16. test: /\.less$/,
  17. use: styleLess.extract({
  18. use: 'css-loader'
  19. })
  20. }
  21. ]
  22. },
  23. plugins: [
  24. styleLess,
  25. resetCss
  26. ]
  27. }

  

通过这样操作后可以打包成两个不同的css文件,如下图

引用图片

  • 处理图片方面,也需要loader
  1. npm i file-loader url-loader -D

  

如果是在css文件里引入的如背景图之类的图片,就需要指定一下相对路径

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.css$/,
  6. use: ExtractTextWebpackPlugin.extract({
  7. use: 'css-loader',
  8. publicPath: '../'
  9. })
  10. },
  11. {
  12. test: /\.(jpe?g|png|gif)$/,
  13. use: [
  14. {
  15. loader: 'url-loader',
  16. options: {
  17. limit: 8192, // 小于8k的图片自动转成base64格式,并且不会存在实体图片
  18. outputPath: 'images/' // 图片打包后存放的目录
  19. }
  20. }
  21. ]
  22. }
  23. ]
  24. }
  25. }

  

在css中指定了publicPath路径这样就可以根据相对路径引用到图片资源了,如下图所示

页面img引用图片

页面中经常会用到img标签,img引用的图片地址也需要一个loader来帮我们处理好

  1. npm i html-withimg-loader -D
  2. module.exports = {
  3. module: {
  4. rules: [
  5. {
  6. test: /\.(htm|html)$/,
  7. use: 'html-withimg-loader'
  8. }
  9. ]
  10. }
  11. }

  

这样再打包后的html文件下img就可以正常引用图片路径了

引用字体图片和svg图片

字体图标和svg图片都可以通过file-loader来解析

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.(eot|ttf|woff|svg)$/,
  6. use: 'file-loader'
  7. }
  8. ]
  9. }
  10. }

  

这样即使样式中引入了这类格式的图标或者图片都没有问题了,img如果也引用svg格式的话,配合上面写好的html-withimg-loader就都没有问题了

添加CSS3前缀

通过postcss中的autoprefixer可以实现将CSS3中的一些需要兼容写法的属性添加响应的前缀,这样省去我们不少的时间

由于也是一个loader加载器,我们也需要先安装一下

  1. npm i postcss-loader autoprefixer -D

  

安装后,我们还需要像webpack一样写一个config的配置文件,在项目根目录下创建一个postcss.config.js文件,配置如下:

  1. module.exports = {
  2. plugins: [require('autoprefixer')] // 引用该插件即可了
  3. }

  

然后在webpack里配置postcss-loader

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.css$/,
  6. use: ['style-loader', 'css-loader', 'postcss-loader']
  7. }
  8. ]
  9. }
  10. }

  

转义ES6

在实际开发中,我们在大量的使用着ES6及之后的api去写代码,这样会提高我们写代码的速度,不过由于低版本浏览器的存在,不得不需要转换成兼容的代码,于是就有了常用的Babel了

Babel会将ES6的代码转成ES5的代码

那么不再多说,既然要使用它,就先来安一下

  1. npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 -D

  

当把这些都安好后,我们就开始配置,由于要兼容的代码不仅仅包含ES6还有之后的版本和那些仅仅是草案的内容,所以我们可以通过一个.babelrc文件来配置一下,对这些版本的支持

  1. // .babelrc
  2. {
  3. "presets": ["env", "stage-0"] // 从右向左解析
  4. }

  

我们再在webpack里配置一下babel-loader既可以做到代码转成ES5了

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test:/\.js$/,
  6. use: 'babel-loader',
  7. include: /src/, // 只转化src目录下的js
  8. exclude: /node_modules/ // 排除掉node_modules,优化打包速度
  9. }
  10. ]
  11. }
  12. }

  

在我们每次npm run build的时候都会在dist目录下创建很多打好的包,如果积累过多可能也会混乱

所以应该在每次打包之前将dist目录下的文件都清空,然后再把打好包的文件放进去

这里提供一个clean-webpack-plugin插件

  1. npm i clean-webpack-plugin -D
  2. let CleanWebpackPlugin = require('clean-webpack-plugin');
  3.  
  4. module.exports = {
  5. plugins: [
  6. // 打包前先清空
  7. new CleanWebpackPlugin('dist')
  8. ]
  9. }

启动静态服务器

启动一个静态服务器,默认会自动刷新,就是说你对html,css,js文件做了修改并保存后,浏览器会默认刷新一次展现修改后的效果

正常情况下我们都是在开发环境中开发项目,所以之前配置的脚本"dev"可以派上用场了,在执行npm run dev命令后,会启动静态服务器,我们访问localhost:3000端口就可以看到开发的页面内容了

如果devServer里open设为true后,会自动打开浏览器

  1. module.exports = {
  2. devServer: {
  3. contentBase: './dist',
  4. host: 'localhost', // 默认是localhost
  5. port: 3000, // 端口
  6. open: true, // 自动打开浏览器
  7. hot: true // 开启热更新
  8. }
  9. }

  

  1. 当然在npm run dev命令下,打包的文件存在于内存中,并不会产生在dist目录下

热更新和自动刷新的区别

在配置devServer的时候,如果hot为true,就代表开启了热更新

But这并没那么简单,因为热更新还需要配置一个webpack自带的插件并且还要在主要js文件里检查是否有module.hot

下面就让我们直接看下代码是如何实现的

  1. // webpack.config.js
  2. let webpack = require('webpack');
  3.  
  4. module.exports = {
  5. plugins: [
  6. // 热更新,热更新不是刷新
  7. new webpack.HotModuleReplacementPlugin()
  8. ],
  9. devServer: {
  10. contentBase: './dist',
  11. hot: true,
  12. port: 3000
  13. }
  14. }
  15.  
  16. // 此时还没完虽然配置了插件和开启了热更新,但实际上并不会生效
  17.  
  18. // index.js
  19. let a = 'hello world';
  20. document.body.innerHTML = a;
  21. console.log('这是webpack打包的入口文件');
  22.  
  23. // 还需要在主要的js文件里写入下面这段代码
  24. if (module.hot) {
  25. // 实现热更新
  26. module.hot.accept();
  27. }

  

以上index.js中的内容,如果将变量a的值进行修改保存后,会在不刷新页面的情况下直接修改掉,这样就实现了热更新

那么热更新从现在看来和自动刷新浏览器的区别也不是太大嘛!自动刷新也是可以接受的啊

其实不然,热更新的好处可能在vue或者react中有更大的发挥,其中某一个组件被修改的时候就会针对这个组件进行热更新了,这里用到vue或react的同学去实际体验一下吧

resolve解析

在webpack的配置中,resolve我们常用来配置别名和省略后缀名

  1. module.exports = {
  2. resolve: {
  3. // 别名
  4. alias: {
  5. $: './src/jquery.js'
  6. },
  7. // 省略后缀
  8. extensions: ['.js', '.json', '.css']
  9. },
  10. }

  

这个配置在webpack中比较简单,我们也就不再叙述了,下面来看点干货

提取公共代码

在webpack4之前,提取公共代码都是通过一个叫CommonsChunkPlugin的插件来办到的。到了4以后,内置了一个一模一样的功能,而且起了一个好听的名字叫“优化”

下面我们就来看看如何提取公共代码

  1. // 假设a.js和b.js都同时引入了jquery.js和一个写好的utils.js
  2. // a.js和b.js
  3. import $ from 'jquery';
  4. import {sum} from 'utils';

  

那么他们两个js中其中公共部分的代码就是jquery和utils里的代码了

可以针对第三方插件和写好的公共文件

  1. module.exports = {
  2. entry: {
  3. a: './src/a.js',
  4. b: './src/b.js'
  5. },
  6. output: {
  7. filename: '[name].js',
  8. path: path.resolve('dust')
  9. },
  10. // 提取公共代码
  11. + optimization: {
  12. splitChunks: {
  13. cacheGroups: {
  14. vendor: { // 抽离第三方插件
  15. test: /node_modules/, // 指定是node_modules下的第三方包
  16. chunks: 'initial',
  17. name: 'vendor', // 打包后的文件名,任意命名
  18. // 设置优先级,防止和自定义的公共代码提取时被覆盖,不进行打包
  19. priority: 10
  20. },
  21. utils: { // 抽离自己写的公共代码,utils这个名字可以随意起
  22. chunks: 'initial',
  23. name: 'utils', // 任意命名
  24. minSize: 0 // 只要超出0字节就生成一个新包
  25. }
  26. }
  27. }
  28. + },
  29. plugins: [
  30. new HtmlWebpackPlugin({
  31. filename: 'a.html',
  32. template: './src/index.html', // 以index.html为模板
  33. + chunks: ['vendor', 'a']
  34. }),
  35. new HtmlWebpackPlugin({
  36. filename: 'b.html',
  37. template: './src/index.html', // 以index.html为模板
  38. + chunks: ['vendor', 'b']
  39. })
  40. ]
  41. }

  

通过以上配置,可以把引入到a.js和b.js中的这部分公共代码提取出来,如下图所示

指定webpack配置文件

在package.json的脚步里,我们可以配置调用不同的webpack配置文件进行打包,举个栗子

这样的好处在于可以针对不同的需求进行一个特定的打包配置
原文地址:https://juejin.im/post/5adea0106fb9a07a9d6ff6de
webpack插件API:https://webpack.docschina.org/plugins/extract-text-webpack-plugin/

  

webpack4配置的更多相关文章

  1. webpack4配置详解之常用插件分享

    前言 继上一次webpack的基础配置分享之后,本次将分享一些工作中项目常用的配置插件.也会包含一些自己了解过觉得不错的插件,如有分析不到位的,欢迎纠错,嗯,这些东西文档都有,大佬可绕过. Wepac ...

  2. 一行一行手敲webpack4配置

    代码:github 一.webpack4--基本配置 这一部分通过webpack的基本配置,使用loader对图片和样式进行打包,从而了解webpack4简单的用方法,保证自己能够配置正确,提升学习动 ...

  3. webpack4配置详解之新手上路初探

    前言 经常会有群友问起webpack.react.redux.甚至create-react-app配置等等方面的问题,有些是我也不懂的,慢慢从大家的相互交流中,也学到了不少. ​ 今天就尝试着一起来聊 ...

  4. CSS Modules入门及React中实践(内附webpack4配置)

    本篇文章以整理为主,自己进行了部分修改,如有侵权,请告知 CSS Modules介绍 CSS Modules是什么东西呢?首先,让我们从官方文档入手:GitHub – css-modules/css- ...

  5. 基于vue-cli 将webpack3 升级到 webpack4 配置

       升级webpack4前 先删除之前的webpack, babel-loader  下载 webpack npm i -D webpack@4 webpack-cli@3 webpack-dev- ...

  6. 多页应用 Webpack4 配置优化与踩坑记录

    前言 最近新起了一个多页项目,之前都未使用 webpack4 ,于是准备上手实践一下.这篇文章主要就是一些配置介绍,对于正准备使用 webpack4 的同学,可以做一些参考. webpack4 相比之 ...

  7. vuecli3.0 webpack4 配置vuex

    废话不说,直接写步骤 1. npm install vux --save 2. npm install less less-loader --save-dev 3. npm install @vux/ ...

  8. 【webpack4】webpack4配置需要注意的问题

    需要注意的知识: 要全局安装webpack以及webpack cli,否则不能使用webpack指令 npm install webpack -g npm install webpack-cli -g ...

  9. webpack4配置react开发环境

    webpack4大大提高了开发效率,简化了配置复杂度,作为一个大的版本更新,作为一个对开发效率执着的爱折腾的程序员,已经忍不住要尝尝鲜了 首先是cli和webpack的分离,开发webpack应用程序 ...

随机推荐

  1. Web前端性能优化的三个偏方

    首先牢骚几句...这一次性能优化针对的模块,初次开发阶段客户给的时间就非常少,俩月时间跳过设计一边需求分析一边编码,最后干出6000+的代码行.最终结果嘛,呵呵,除开一堆bug不说,性能就是个非常大的 ...

  2. MyBatis学习(一)---配置文件,Mapper接口和动态SQL

    MyBatis MyBatis官方学习网站 http://www.mybatis.org/mybatis-3/zh/index.html 为什么需要MyBatis? Jdbc操作数据库的不足之处 1. ...

  3. 关于iFrame特性总计和iFrame跨域解决办法

    1.iframe 定义和用法 iframe 元素会创建包含另外一个文档的内联框架(即行内框架). HTML 与 XHTML 之间的差异 在 HTML 4.1 Strict DTD 和 XHTML 1. ...

  4. RegExp对象的exec方法

    RegExp对象的exec方法和String对象的match方法用法十分相似,分两篇博客讲讲其各自的用法和它们之间的异同. 下一篇讨论match方法的用法和两者的异同. 定义及语法 [定义] exec ...

  5. java停止一个线程

    Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...

  6. Javascript获取For循环所用时间

    第一种: let tOne = new Date().getTime(); let n = new Date(); let hour = n.getHours() < 10 ? "0& ...

  7. Angular进阶教程一

    6 AngularJS进阶 6.1数据绑定原理研究 Angular用户都想知道数据绑定是怎么实现的.你可能会看到各种各样的词汇:$watch.$apply.$digest.dirty-checking ...

  8. 软工读书笔记 week3 (《黑客与画家》上)

    一.何谓黑客? 黑客,在我们大多数普通人眼里,就是入侵计算机的人,通常还与干坏事挂钩.而书中告诉我们,这 并不是它的真正含义.而要想理解这本书,就要首先理解什么是黑客. 黑客这个词最初起源时,完全是一 ...

  9. linux整个日志目录查询记录

    在linux下面需要查看整个目录的日志,搜索用户的一个行为.因为不知道具体是那一天,一个个的查询也可以,但是太麻烦.可以用过下面的命令来实现: rep -iRl  "关键字" ./ ...

  10. 【Yii系列】Yii2.0的安装与调试

    接上一节的话,我们最终选择了Yii框架作为我们的主要开发框架,今天,我就和大伙来聊聊如何安装与调试Yii2.0,以及后续会和大伙聊聊如何在Yii2.0上快速撸代码. Yii2.0的安装 好的,Comp ...