最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从0开始搭建一个React开发框架

    正文概述 掘金(huomarvin)   2021-02-06   902

    起因

    在公司入职也很久了,发现很多下面的同学都不理解我们所用开发框架是如何搭建起来的,为了加强小伙伴们的基础功底,所以有了这篇文章。

    此次我会带领大家一步步的来搭建一个开发框架,一共分四篇文章来写。

    • 基础React开发框架的搭建
    • 基础的node端抽取
    • cli集成
    • 开发规范

    本文会实现什么

    从0到1搭建一个基于webpack的react应用

    搭建

    准备工作

    先来介绍一下我的开发环境

    • MacBook
    • node@15.5.0
    • yarn@1.22.10

    在进行下一步前为了加快我们的下载速度,请先执行如下命令

    npm install -g yarn
    npm install -g nrm 
    npm install -g n
    
    nrm use taobao
    
    # 设置依赖安装过程中内部模块下载Node的淘宝镜像
    npm config set disturl https://npm.taobao.org/mirrors/node/
    # 设置常用模块的淘宝镜像
    npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/
    npm config set sharp_dist_base_url https://npm.taobao.org/mirrors/sharp-libvips/
    npm config set electron_mirror https://npm.taobao.org/mirrors/electron/
    npm config set puppeteer_download_host https://npm.taobao.org/mirrors/
    npm config set phantomjs_cdnurl https://npm.taobao.org/mirrors/phantomjs/
    npm config set sentrycli_cdnurl https://npm.taobao.org/mirrors/sentry-cli/
    npm config set sqlite3_binary_site https://npm.taobao.org/mirrors/sqlite3/
    npm config set python_mirror https://npm.taobao.org/mirrors/python/
    

    本文会用到的全局的node模块

    npm install -g http-server
    

    代码篇

    首先我们先来创建一个简单的开发项目

    cd ~/Documents
    mkdir react-base && cd react-base
    yarn init -y
    mkdir src config types public
    

    我们现在的目录结构是这样的

    ├── config  存放webpack配置文件
    ├── package.json
    ├── public  存放与业务无关的静态资源文件
    ├── src	 存放入口文件和业务相关代码
    └── types 存放ts声明文件
    

    我们先来安装一下我们的模块化打包工具webpack

    yarn add webpack webpack-cli -D
    

    src目录下创建main.js文件当做入口文件,执行如下命令

    echo "console.log('Hello World');" > src/index.js
    

    此时运行yarn webpack,会发现在dist目录下生成一个main.js文件,可以看到如下是webpack的工作机制。 从0开始搭建一个React开发框架

    因为webpack只对模块化语法exportimport 提供了支持,对于es6的其他语法并没有提供支持,此处我们要编译es6jsx语法,需要使用babelwebpack的工作机制是先通过loader对静态资源进行转换后输出到目标文件,此处引入babel-loader,并在根目录下创建.babelrc文件提供配置,如下是babel为我们完成的转换工作。 从0开始搭建一个React开发框架

    yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react -D
    yarn add react react-dom
    touch .babelrc
    

    在.babelrc文件中配置如下

    {
        "presets": [
            "@babel/preset-env", "@babel/preset-react"
        ]
    }
    

    创建src/App.js,内容如下:

    import React from 'react';
    
    const App = () => {
      return <div>Hello World</div>
    }
    
    export default App;
    

    修改index.js,内容如下

    import React from 'react';
    import ReactDom from 'react-dom';
    import App from './App';
    
    ReactDom.render(<App />, document.getElementById('root'))
    

    在项目根目录下创建webpack.config.mjs文件,此处使用mjs后缀是为了避免在同一个项目中既使用CommonJs也是用ES Module,内容如下

    import path from 'path';
    
    const config = {
        entry: './src/index.js',
        output: {
            path: path.resolve(path.resolve(), 'dist'),
            filename: 'bundle.js'
        },
        module: {
            rules: [{
                test: /\.m?jsx?$/,
                exclude: /node_modules/,
                use: 'babel-loader'
            }],
        }
    };
    
    export default config;
    

    要想让代码能够跑起来,我们还需要一个html文件,在dist目录下,创建index.html文件,内容如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="root"></div>
        <script src="bundle.js"></script>
    </body>
    </html>
    

    此时我们执行yarn webpack --mode none,可以看到有文件dist/bundle.js文件生成,将该文件进行折叠,可以看到是一个立即执行函数,有兴趣的小伙伴可以仔细看一下里面的内容,此时我们通过上面安装的http-server来启动一个http服务器,执行命令http-server dist,可以看到已经为我们启动了8080端口。 从0开始搭建一个React开发框架

    通过浏览器打开http://127.0.0.1:8080,我们可以看到是白屏的,打开console可以看到如下报错 从0开始搭建一个React开发框架

    我们分析一下打包后的代码,可以看到会根据环境变量的配置来判断引入是引入开发版本的react还是生产版本的react,此时process变量没有被定义。 从0开始搭建一个React开发框架

    我们可以借助于webpack插件机制来解决该问题, 我们在webpack.config.mjsmodule节点下添加如下代码

    + import webpack from 'webpack';
    
    const config = {
    	...,
        plugins: [
          new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development')
          })
        ]
    }
    

    重新打包yarn webpack --mode none,可以看到process.env.NODE_ENV === 'production'已经被替换成false。重新运行清空缓存刷新一下,可以看到页面上已经显示出Hello World,代表我们的程序没有问题。 从0开始搭建一个React开发框架

    此处有一个问题就是html文件和bundle文件都是我们写死的,我们可以使用webpack的另外一个插件html-webpack-plugin,来根据模板来生成index.html文件,并动态注入打包后的js文件。

    创建文件src/index.html,内容如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div id="root"></div>
    </body>
    </html>
    

    安装依赖

    yarn add html-webpack-plugin -D
    

    更改webpack.config.mjs,添加如下内容

    ...
    + import HtmlWebpackPlugin from 'html-webpack-plugin';
    
    const config = {
    	...
        plugins: [
        	...
    +         new HtmlWebpackPlugin({
    +            template: './src/index.html',
    +            inject: 'body'
    +        })
        ]
    };
    

    运行yarn webpack --mode none,可以看到生成的在dist目录下生成的index.html文件中已经自动注入了bundle.js从0开始搭建一个React开发框架

    引入typescript

    同样的我们的框架也要支持typescript,我们将src/app.js更改为src/app.tsx,内容不变,此处我们要添加ts相关的依赖的内容。

    yarn add typescript ts-loader -D
    yarn add @types/react @types/react-dom -D
    yarn tsc --init
    

    此时根目录下会生成一个tsconfig.json文件,我们不需要做过多的配置,将jsx节点放开,并配置为react,如下

    "jsx": "react",            
    

    webpack.config.mjs文件的rules节点下添加如下内容

    {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 'ts-loader'
    },
    

    output节点下添加如下内容,此处的内容是为了避免添加后缀。

    resolve: {
        extensions: ['.mjs', '.js', '.json', ".ts", ".tsx"],
    },
    

    现在目录结构如下

    ├── config
    ├── dist
    │   ├── bundle.js
    │   └── index.html
    ├── package.json
    ├── public
    ├── src
    │   ├── App.tsx
    │   ├── index.html
    │   └── index.js
    ├── tsconfig.json
    ├── types
    ├── webpack.config.mjs
    └── yarn.lock
    

    执行yarn webpack --mode none同样可以正常显示。

    添加css/less/scss支持

    添加所用loader

    yarn add style-loader css-loader less-loader sass-loader less sass -D 
    

    添加测试文件src/index.css,src/index.less,src/index.scss。 src/index.css

    .css {
        background-color: #f00;
    }
    
    .less {
        background-color: #0f0;
    }
    
    .scss {
        background-color: #00f;
    }
    

    src/App.tsx代码如下

    import React from 'react';
    import './index.css';
    import './index.less';
    import './index.scss';
    
    const App = () => {
      return <div>
        <h1 className="css">Hello CSS</h1>
        <h1 className="less">Hello Less</h1>
        <h1 className="scss">Hello SCSS</h1>
      </div>
    }
    
    export default App;
    

    webpack.config.mjsrules节点下添加如下内容

    {
      test: /\.css$/i,
      use: ['style-loader', 'css-loader'],
    },
    {
      test: /\.less$/,
      use: ['style-loader', 'css-loader', 'less-loader'],
    },
    {
      test: /\.s[ac]ss$/i,
      use: [
        "style-loader",
        "css-loader",
        "sass-loader",
      ],
    },
    

    使用yarn webpack --mode none进行打包,然后用http-server dist启动,访问http://127.0.0.1:8080/ 发现已经可以正常显示了。

    从0开始搭建一个React开发框架

    简单介绍一下各个loader的作用,sass-loaderless-loader是将.scss.less代码转换成.css代码,而css-loader的作用是将css的代码转换成js脚本,style-loader的作用是将生成的css文件嵌入到style标签中,简单看一下打包后的代码可以看到webpackcss代码当做一个模块放到了IIFE中。 从0开始搭建一个React开发框架 从0开始搭建一个React开发框架

    静态资源

    我们在开发过程中也会使用到一些静态资源,比方说图片,此处为图片添加依赖,在webpack@5版本下,我们一般会使用file-loaderurl-loaderfile-loader来处理一些比较大的文件内容,而url-loader则处理一些小的文件内容。在webpack@5版本中功能已经被优化,请看如下描述。 从0开始搭建一个React开发框架

    我们新建一个页面src/pages/Home.tsx,内容如下

    import React from 'react';
    import git from '@static/img/git.png';
    
    const Home = () => {
        return <div>
            <h1>Home</h1>
            <img src={git} />
        </div>
    }
    
    export default Home;
    

    添加图片src/static/img/git.png

    此时我们可以看到已经编译报错了,错误信息如下:

    找不到模块“@static/img/git.png”或其相应的类型声明。
    

    这个地方是因为ts没有办法解析.png的类型声明,我们在创建types/static.d.ts文件,内容如下

    declare module '*.svg'
    declare module '*.png'
    declare module '*.jpg'
    declare module '*.jpeg'
    declare module '*.gif'
    declare module '*.bmp'
    declare module '*.tiff'
    

    此处因为我们不想一直通过相对路径的方式去找文件,所以我们对文件路径定义了别名,更改webpack.config.mjs,在extensions节点下添加如下配置

    alias: {
       '@pages': path.resolve(path.resolve(), './src/pages/'),
       '@components': path.resolve(path.resolve(), './src/components/'),
       '@static': path.resolve(path.resolve(), './src/static/'),
    },
    

    更改tsconfig.json,添加如下配置

    "baseUrl": "./",
      "paths": {
        "@pages/*": [
          "./src/pages/"
        ],
        "@static/*": [
          "./src/static/"
        ],
        "@components/*": [
          "./src/components/"
        ]
      },
    

    然后我们添加loader对图片文件进行处理,在webpack.config.mjsrules节点下添加如下内容。

     {
       test: /\.png/,
       type: 'asset/resource'
     }
    

    再运行打包,我们可以发现已经有一个图片文件被打包到了dist目录下。 从0开始搭建一个React开发框架

    简单分析一下打包后的文件,我们发现loader只是对文件名进行了处理,然后放入到了模块中。 从0开始搭建一个React开发框架

    另外一种比较常规的静态资源打包是如下的方式,这个时候webpack会将文件转换成data:url的形式放入到bundle.js文件中,这种方式只建议小文件去使用,若太大则会影响到bundle.js文件的体积,如下图,可以看到是一个很长的字符串。

    {
      test: /\.svg/,
      type: 'asset/inline',
    }
    

    从0开始搭建一个React开发框架

    加快我们的开发步骤

    上面的操作都是我们手动去完成的,目的是为了加深大家对打包过程的理解,真实开发过程中我们不会把生成文件直接写入到磁盘上,而是会放到内存中,加快编译速度。

    webpack-dev-server会我们的开发过程提供了更好的体验,他的便利如下

    • 提供http-server
    • 提供热更新
    • 提供代理

    下面让我们来一步步的使用webpack-dev-server

    提供http-server

    安装依赖

    yarn add webpack-dev-server -D
    

    更改package.json脚本,在跟节点下添加如下脚本

    "scripts": {
      "start": "webpack serve --mode development"
    },
    

    此时浏览器已经为我们开启了8080端口 有些静态资源例如favicon.ico放入到public目录下,想要让应用访问到这个文件,就需要为webpack-dev-server添加一个静态资源的路径转发,在webpack.config.mjsconfig对象上添加如下属性

    devServer: {
        contentBase: path.join(path.resolve(), './public'),
    },
    

    此时运行yarn start可以看到webpack已经开始长期监听文件的变化,并自动进行了编译,打开http://localhost:8080/可以看到favicon.ico也已经被正常加载了。

    提供热更新

    在我们的开发过程中,不想每次更改代码后都要手工去刷新浏览器,那webpack-dev-server为我们提供了自动刷新浏览器的配置,我们在webpack.config.mjsdevServer属性上添加hotOnly:true,此时我们去修改css文件,可以发现浏览器已经自动的刷新了。

    这个地方有的同学可能会好奇为什么js文件就没有提供这样的功能呢,这是因为css的处理是比较common的,所以style-loader已经进行了处理。

    从0开始搭建一个React开发框架

    js则需要我们根据使用框架的不同来定制化处理,好在社区已经有了现成的方案,我们选用react-hot-loader,下面我们来安装一下

    yarn add react-hot-loader @hot-loader/react-dom
    

    .babelrc中添加plugins,如下

    {
      "plugins": ["react-hot-loader/babel"]
    }
    

    src/App.tsx进行调整,调整后代码如下

    + import { hot } from 'react-hot-loader/root';
    import React from 'react';
    import './index.css';
    import './index.less';
    import './index.scss';
    import Home from '@pages/Home';
    
    const App = () => {
      return <div>
        <h1 className="css">Hello CSS</h1>
        <h1 className="less">Hello Less</h1>
        <h1 className="scss">Hello SCSS</h1>
        <Home />
      </div>
    }
    - export default App;
    + export default hot(App);
    

    停掉服务重新运行yarn start一下,此时我们在App组件中添加一个输入框,然后在页面上输入内容123,然后在App组件中在添加一个输入框,发现第一个输入框的内容并没有消失,第二个输入框也同样被添加上去了,代表热重载成功。

    从0开始搭建一个React开发框架

    提供代理

    一个基于ReactSPA应用,一般都会向服务端发起请求,而浏览器的安全策略经常会让我们遇到跨域的问题,此处我们使用github/users接口来模拟一个简单的应用。

    先安装所需依赖

    yarn add axios
    

    创建文件src/pages/Users/index.tsx,文件内容如下

    import React, { useEffect, useState } from 'react';
    import axios from 'axios';
    
    interface User {
        login: string;
    }
    
    const Users = () => {
        const [users, setUsers] = useState<Array<User>>([])
        useEffect(() => {
            axios.get('/api/users').then(res => {
                setUsers(res.data)
            })
        }, []);
        return <>
            <ul>
                {users.map(item => <li key={item.login}>{item.login}</li>)}
            </ul>
        </>
    }
    
    export default Users;
    

    此时我们需要在webpack.config.mjs文件为其配置代理,内容如下:

    devServer {
    	...
        proxy: {
          '/api': {
            target: 'https://api.github.com/',
            pathRewrite: { '^/api': '' },
            changeOrigin: true
          }
        }
    }
    
    

    App.tsx文件中引入该组件,并放到Home组件后,重启后可以发现user列表已经正常的展现出来了。 src/App.tsx

    ...
    import Users from '@pages/Users';
    
    const App = () => {
    	return (
        	...
            <Users />
        );
    }
    

    从0开始搭建一个React开发框架

    生产环境配置

    现在我么已经有了一套可以在开发环境使用的框架,但是在开发环境和生产环境我们的打包策略是不一样的,此时我们对webpack配置文件进行抽取,将公共各部分放到webpack.base.mjs文件中,通过webpack-merge对配置进行结合,更改我们现有的文件结构,如下

    ├── config
    │   ├── webpack.base.mjs
    │   ├── webpack.dev.mjs
    │   └── webpack.prd.mjs
    ├── package.json
    ├── public
    │   └── favicon.ico
    ├── src
    │   ├── App.tsx
    │   ├── index.css
    │   ├── index.html
    │   ├── index.js
    │   ├── index.less
    │   ├── index.scss
    │   ├── pages
    │   │   ├── Home
    │   │   │   └── index.tsx
    │   │   └── Users
    │   │       └── index.tsx
    │   └── static
    │       └── img
    │           └── git.png
    ├── tsconfig.json
    ├── types
    │   └── static.d.ts
    └── yarn.lock
    

    安装所需依赖

    yarn add webpack-merge -D 
    

    调整后config/webpack.base.mjs文件内容如下

    import path from 'path';
    import HtmlWebpackPlugin from 'html-webpack-plugin';
    
    const config = {
        entry: './src/index.js',
        output: {
            path: path.resolve(path.resolve(), './dist'),
            filename: 'bundle.js'
        },
        resolve: {
            extensions: ['.mjs', '.js', '.json', ".ts", ".tsx"],
            alias: {
                '@pages': path.resolve(path.resolve(), './src/pages/'),
                '@components': path.resolve(path.resolve(), './src/components/'),
                '@static': path.resolve(path.resolve(), './src/static/'),
            },
        },
        module: {
            rules: [
                {
                    test: /\.m?jsx?$/,
                    exclude: /node_modules/,
                    use: 'babel-loader'
                },
                {
                    test: /\.tsx?$/,
                    exclude: /node_modules/,
                    use: 'ts-loader'
                },
                {
                    test: /\.png/,
                    type: 'asset/inline'
                }
            ],
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: './src/index.html',
                inject: 'body'
            })
        ],
    };
    
    export default config;
    

    调整后config/webpack.dev.mjs内容如下

    import { merge } from 'webpack-merge';
    import base  from './webpack.base.mjs';
    import path from 'path';
    import webpack from 'webpack';
    
    export default merge(base, {
      mode: 'development',
      devtool: 'eval-cheap-module-source-map',
      devServer: {
        contentBase: path.join(path.resolve(), './public'),
        hotOnly: true,
        proxy: {
          '/api': {
            target: 'https://api.github.com/',
            pathRewrite: { '^/api': '' },
            changeOrigin: true
          }
        }
      },
      resolve: {
        alias: {
          'react-dom': '@hot-loader/react-dom',
        },
      },
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: ['style-loader', 'css-loader'],
          },
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader'],
          },
          {
            test: /\.s[ac]ss$/i,
            use: [
              "style-loader",
              "css-loader",
              "sass-loader",
            ],
          },
        ]
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env.NODE_ENV': JSON.stringify('development')
        }),
      ]
    })
    

    优化后的config/webpack.prd.mjs内容如下

    import { CleanWebpackPlugin } from 'clean-webpack-plugin';
    import { merge } from 'webpack-merge';
    import CopyPlugin from "copy-webpack-plugin";
    import MiniCssExtractPlugin from 'mini-css-extract-plugin';
    import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
    import base from './webpack.base.mjs';
    import webpack from 'webpack';
    
    export default merge(base, {
        mode: 'production',
        devtool: false,
        module: {
            rules: [
                {
                    test: /\.css$/i,
                    use: [MiniCssExtractPlugin.loader, 'css-loader'],
                },
                {
                    test: /\.less$/,
                    use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],
                },
                {
                    test: /\.s[ac]ss$/i,
                    use: [
                        MiniCssExtractPlugin.loader,
                        "css-loader",
                        "sass-loader",
                    ],
                },
            ],
        },
        optimization: {
            minimize: true,
            minimizer: [
                // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
                `...`,
                new CssMinimizerPlugin(),
            ],
        },
        plugins: [
            new CleanWebpackPlugin(),
            new CopyPlugin({
                patterns: [
                    { from: "public", to: "." },
                ]
            }),
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': JSON.stringify('production')
            }),
            new MiniCssExtractPlugin(),
        ],
    })
    

    此次添加了几个插件, 简单来介绍一下作用。

    • clean-webpack-plugin在每次打包前清空dist目录下内容
    • copy-webpack-plugin打包的时候将public目录下的内容拷贝到dist目录下
    • mini-css-extract-pluginbundle.js中的样式文件抽取到css文件中
    • css-minimizer-webpack-plugin 对抽取的css文件进行压缩。

    更改package.json中的scripts

    "start": "webpack serve  --config config/webpack.dev.mjs",
    "build:prd": "webpack --config config/webpack.prd.mjs"
    

    安装依赖并执行构建

    yarn add clean-webpack-plugin -D
    yarn add copy-webpack-plugin -D
    yarn add mini-css-extract-plugin -D
    yarn add css-minimizer-webpack-plugin -D
    yarn build:prd
    

    下图是打包后的内容,可以看到未通过gzip压缩的bundle.js大小为143k

    从0开始搭建一个React开发框架

    按需加载

    当我们的项目越来越大后,bundle.js文件的大小也会随之增大,那么页面的加载速度也会变慢,这个时候我们可以引入按需加载,也就是lazy load,当我们需要用到一个组件的时候,再去加载这个页面的内容。 让我们来改进一下我们的项目,此处我们使用的是@loadable/component,为了体现出效果引入react-router

    yarn add react-router react-router-dom @loadable/component 
    yarn add @types/react-router @types/react-router-dom @types/loadable__component -D
    

    修改src/App.jssrc/App.tsx,目前发现以.tsx为后缀的文件实现按需加载,此问题后续进行补充。 src/App.js内容如下

    import { hot } from 'react-hot-loader/root';
    import React from 'react';
    import './index.css';
    import './index.less';
    import './index.scss';
    import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
    import loadable from "@loadable/component";
    
    const Loading = () => {
      return <div>Loading...</div>
    }
    
    const Home = loadable(() => import("@pages/Home"), {
      fallback: <Loading />
    });
    const Users = loadable(() => import("@pages/Users"), {
      fallback: <Loading />
    });
    
    const App = () => {
      return <div>
        <h1 className="css">Hello CSS</h1>
        <h1 className="less">Hello Less</h1>
        <h1 className="scss">Hello SCSS</h1>
        return <>
          <Router>
            <div>
              <nav>
                <ul>
                  <li><Link to="/">Home</Link></li>
                  <li><Link to="/users">Users</Link></li>
                </ul>
              </nav>
              <main>
                <input />
                <Switch>
                  <Route path="/" exact>
                    <Home />
                  </Route>
                  <Route path="/users">
                    <Users />
                  </Route>
                </Switch>
              </main>
            </div>
          </Router>
        </>
      </div>
    }
    
    export default hot(App);
    

    .babelrc添加plugin

    {
        "presets": [
            "@babel/preset-env",
            "@babel/preset-react"
        ],
        "plugins": [
            "react-hot-loader/babel",
            "@babel/plugin-syntax-dynamic-import"
        ]
    }
    

    执行yarn build:prd,可以看到每个路由都进行了切分 从0开始搭建一个React开发框架

    此时dist目录下的内容我们就可以和服务端代码部署到一起使用了。


    起源地下载网 » 从0开始搭建一个React开发框架

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元