Создайте интерфейсную архитектуру Vue с нуля (1)

Архитектура Vue.js Webpack vue-router

предисловие

Подумайте об этом, и я сделал много архитектурных проектов, некоторые из которых основаны на vue, основаны на реакции, основаны на thinkPHP и основаны на laravel.

Если вы сделаете слишком много, у вас будут разные представления о существующей архитектуре, как хорошие, так и плохие, короче говоря, пользоваться ею все равно неудобно. Хотя vue-cli можно собрать и использовать очень быстро, особенно vue-cli v3.0, который инкапсулирует webpack@vue/cliВ SDK он более чистый и лаконичный в использовании.

Но, для тех из нас, кто любит бросать, ну, просто шучу. Однако нам снова пришлось внести более или менее изменения в оптимизацию страницы, а также в архитектуру проекта.

Ладно, введение закончено, теперь я начну с нуля и шаг за шагом построю архитектуру фронтенда с полностью разделенными фронтендом и бэкендом.

шаг

Так как предьявлений много, то это все написано в одной статье, а некоторые слишком длинные.

Итак, я бы разделил на:

  1. Создайте файл конфигурации webpack в среде разработки

  2. Настроить eslint, babel, postcss

  3. Создать файлы проекта, структуру каталогов

  4. Реализовать моделирование локального интерфейса данных с помощью koa

  5. Создайте файл конфигурации веб-пакета в среде выпуска.

  6. Создайте файлы конфигурации веб-пакета в тестовой среде и тестовые примеры (TODO).

  7. Автоматически инициализировать проект сборки (TODO)

Эти семь глав представлены отдельно.

развивать

Во-первых, проект инициализации

  1. Создать папку проекта мы называемvue-constructБар

  2. инициализировать gitgit init

  3. инициализировать нпмnpm init

  4. Создать файл проекта Чтобы запустить веб-пакет, вместо того, чтобы просто говорить о конфигурации без его запуска, он немного пуст, поэтому давайте сначала создадим несколько файлов и каталогов проекта. Перед этим установим два пакета: vue, vue-router,npm i -S vue vue-router. Мы помещаем файлы, связанные с кодом проекта, в файл с именемappпод папку. Сначала я создал их все, а затем представил их один за другим.

├── app
│   ├── app.vue
│   ├── common
│   │   ├── img
│   │   ├── js
│   │   └── scss
│   ├── index.html
│   ├── index.js
│   ├── router
│   │   └── index.js
│   └── views
│       └── home
│           └── index.vue
├── .gitignore
├── package-lock.json
├── package.json
└── webpack.config.js

node_modules игнорируется.

Папка использовать
app.vue как основной файл vue
common Поместите публичный код внутри
index.html файл шаблона страницы
index.js Основной входной файл проекта
router Поместите файл маршрутизатора, соответствующий vue
views положить файл просмотра
.gitignore игнорировать node_module

Нам пока все равно, какой именно код в этих файлах, и мы поговорим об этом, когда вебпак будет настроен.

2. Настройте webpack.config.js

  1. Установите серию пакетов: Чтобы веб-пакет работал, его необходимо установить.
webpack
webpack-dev-server

Для обработки одностраничных файлов vue установите:

vue-loader

Для обработки файлов scss и извлечения из js установите:

node-sass
style-loader
css-loader
sass-loader
vue-style-loader
postcss
postcss-loader
autoprefixer
extract-text-webpack-plugin

Для обработки файлов изображений и шрифтов установите:

file-loader
url-loader

Для поддержки расширенного синтаксиса-babel установите:

babel
babel-loader
babel-plugin-syntax-dynamic-import
babel-plugin-transform-object-rest-spread
babel-polyfill
babel-preset-env

Чтобы проверить формат кода-eslint, установите:

eslint
eslint-loader
eslint-plugin-html
babel-eslint
  1. Настройте файл webpack.config.js
const webpack = require('webpack')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
// 为了抽离出两份CSS,创建两份ExtractTextPlugin
// base作为基础的css,基本不变,所以,可以抽离出来充分利用浏览器缓存
// app作为迭代的css,会经常改变
const isProduction = process.env.NODE_ENV === 'production'
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const extractBaseCSS =
  new ExtractTextPlugin(
    {
      filename:'static/css/base.[chunkhash:8].css',
      allChunks: true,
      disable: !isProduction // 开发环境下不抽离css
    }
  )
const extractAppCSS
  = new ExtractTextPlugin(
    {
      filename:'static/css/app.[chunkhash:8].css',
      allChunks: true,
      disable: !isProduction // 开发环境下不抽离css
    }
  )

// 减少路径书写
function resolve(dir) {
  return path.join(__dirname, dir)
}

// 网站图标配置
const favicon = resolve('favicon.ico')

// __dirname: 总是返回被执行的 js 所在文件夹的绝对路径
// __filename: 总是返回被执行的 js 的绝对路径
// process.cwd(): 总是返回运行 node 命令时所在的文件夹的绝对路径
const config = {
  // sourcemap 模式
  devtool: 'cheap-module-eval-source-map',
  // 入口
  entry: {
    app: resolve('app/index.js')
  },
  // 输出
  output: {
    path: resolve('dev'),
    filename: 'index.bundle.js'
  },
  resolve: {
    // 扩展名,比如import 'app.vue',扩展后只需要写成import 'app'就可以了
    extensions: ['.js', '.vue', '.scss', '.css'],
    // 取路径别名,方便在业务代码中import
    alias: {
      api: resolve('app/api/'),
      common: resolve('app/common/'),
      views: resolve('app/views/'),
      components: resolve('app/components/'),
      componentsBase: resolve('app/componentsBase/'),
      directives: resolve('app/directives/'),
      filters: resolve('app/filters/'),
      mixins: resolve('app/mixins/')
    }
  },
  // loaders处理
  module: {
    rules: [
      {
        test: /\.js$/,
        include: [resolve('app')],
        loader: [
          'babel-loader',
          'eslint-loader'
        ]
      },
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        loader: 'vue-loader',
        options: {
          extractCSS: true,
          loaders: {
            scss: extractAppCSS.extract({
              fallback: 'vue-style-loader',
              use: [
                {
                  loader: 'css-loader',
                  options: {
                    sourceMap: true
                  }
                },
                {
                  loader: 'postcss-loader',
                  options: {
                    sourceMap: true
                  }
                },
                {
                  loader: 'sass-loader',
                  options: {
                    sourceMap: true
                  }
                }
              ]
            })
          }
        }
      },
      {
        test: /\.(css|scss)$/,
        use: extractBaseCSS.extract({
          fallback: 'style-loader',
          use: [
            {
              loader: 'css-loader',
              options: {
                sourceMap: true
              }
            },
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: true
              }
            },
            {
              loader: 'sass-loader',
              options: {
                sourceMap: true
              }
            }
          ]
        })
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 8192,
          name: isProduction
            ? 'static/img/[name].[hash:8].[ext]'
            : 'static/img/[name].[ext]'
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 8192,
          name: isProduction
            ? 'static/font/[name].[hash:8].[ext]'
            : 'static/font/[name].[ext]'
        }
      }
    ]
  },
  plugins: [
    // html 模板插件
    new HtmlWebpackPlugin({
      favicon,
      filename: 'index.html',
      template: resolve('app/index.html')
    }),
    // 抽离出css
    extractBaseCSS,
    extractAppCSS,
    // 热替换插件
    new webpack.HotModuleReplacementPlugin(),
    // 更友好地输出错误信息
    new FriendlyErrorsPlugin()
  ],
  devServer: {
    proxy: {
      // 凡是 `/api` 开头的 http 请求,都会被代理到 localhost:7777 上,由 koa 提供 mock 数据。
      // koa 代码在 ./mock 目录中,启动命令为 npm run mock。
      '/api': {
        target: 'http://localhost:7777', // 如果说联调了,将地址换成后端环境的地址就哦了
        secure: false
      }
    },
    host: '0.0.0.0',
    port: '9999',
    disableHostCheck: true, // 为了手机可以访问
    contentBase: resolve('dev'), // 本地服务器所加载的页面所在的目录
    // historyApiFallback: true, // 为了SPA应用服务
    inline: true, //实时刷新
    hot: true  // 使用热加载插件 HotModuleReplacementPlugin
  }
}

module.exports = {
  config: config,
  extractBaseCSS: extractBaseCSS,
  extractAppCSS: extractAppCSS
}

Суммировать

Эта статья в основном делала три вещи:

  1. Создайте простую структуру проекта
  2. Установил это и позже использовал пакет npm
  3. Настройте Webpack для среды разработки

Далее настроим eslint, babel, postcss —Создайте интерфейсную архитектуру Vue с нуля (2)

Полный код проекта

Интерфейсная архитектура Vue — by sub 咻