Создайте полную среду разработки Vue3 с помощью Webpack5 с нуля.

внешний интерфейс

предисловие

Зачем строить колеса? Разве официальные леса не благоухают? Создание колес предназначено только для того, чтобы углубить наше понимание технологии и понять основные знания, лежащие в ее основе, на основе знания того, как ее использовать, чтобы мы могли гибко использовать ее знания в различных деловых потребностях для достижения эффекта получения вдвое больше. результат с половиной усилий~

Ниже приведены некоторые из наиболее важных знаний, которые я извлек из реальной среды разработки проектов, созданной компанией в рамках внутреннего обмена технологиями.

Далее мы используемWebpack5построить полныйVue3среда разработки! ! !

каталог инициализации

Шаг 1: Инициализацияpackage.json

npm init -y

Шаг 2: Установкаwebpack

npm install webpack webpack-cli -D

Уведомление:

  1. -DЭквивалентно--save-dev; Требуемые зависимости для среды разработки
  2. -SЭквивалентно--save;Зависимости для производства

Шаг 3: Инициализируйте каталоги и файлы

  • Создайтеwebpack.config.jsфайл для записиwebpackнастроить

    // webpack.config.js
    const path = require('path');
    
    module.exports = {
        mode: 'development',
        entry: './src/index.js',
        output: {
            filename: '[name].js',
            path: path.resolve(__dirname, 'dist')
        }
    }
    
  • Создайтеsrcкаталог для хранения исходного кода

    // src/index.js
    console.log('test webpack')
    
  • Исправлятьwebpack.config.jsсерединаscriptsполе

    {
      // ...
      "scripts": {
        "build": "webpack"
      },
      // ....
    }
    
    
  • Пакет

В терминале корневого каталога проекта введите:npm run buildВот и все!

После успешной установки пакета он будет автоматически создан в корневом каталоге проекта.distпапка, внутриmain.jsФайл — это файл после того, как мы его упаковали.

Настройка основных функций

Конвертировать ES6+ в ES5

Поскольку некоторые браузеры не могут анализироватьES6+и другие грамматики высокого уровня, поэтому их необходимо преобразовать в грамматики низкого уровня, которые могут анализировать браузеры (например, браузеры IE)

Шаг 1: Установите зависимости

npm install @babel/core babel-loader @babel/preset-env -D

Шаг 2: Изменитьwebpack.config.jsнастроить

const path = require('path');

module.exports = {
    // ...
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            }
        ]
    }
}

Уведомление: Если вы не хотите записывать конфигурацию в файл конфигурации, вы можете создать ее в корневом каталоге проекта.babel.config.jsилиbabelrc.jsдокумент.

стиль обработки

из-заwebpackПо умолчанию только обработка пакетовcommonJsнормативныйjsДля обработки других файлов требуется соответствующий процессор.

Шаг 1: Установите зависимости

npm install style-loader css-loader less less-loader -D

Шаг 2: Изменитьwebpack.config.jsнастроить

const path = require('path');

module.exports = {
    // ...
    module: {
        rules: [
            // ...
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            }
        ]
    }
}

Уведомление:loaderВ конфигурации есть много оптимизаций, которые будут подробно описаны позже в [Оптимизация].

Обработка статических ресурсов, таких как изображения

Аналогично, кромеjsфайл другой файл упаковкаwebpackВсе требуют определенного процессора для обработки.

Шаг 1: Установите зависимости

npm install url-loader file-loader -D

Шаг 2: Изменитьwebpack.config.jsнастроить

const path = require('path');

module.exports = {
    // ...
    module: {
        rules: [
            // ...
            {
                test: /\.(jpg|png|jpeg|gif|bmp)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 1024,
                        fallback: {
                            loader: 'file-loader',
                            options: {
                                name: '[name].[ext]'
                            }
                        }
                    }
                }
            },
            {
                test: /\.(mp4|ogg|mp3|wav)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 1024,
                        fallback: {
                            loader: 'file-loader',
                            options: {
                                name: '[name].[ext]'
                            }
                        }
                    }
                }
            }
        ]
    }
}

создать html-файл

Как мы делаем упакованныеjsФайл автоматически вставляется в html шаблон?

Шаг 1: Установите зависимости

npm install html-webpack-plugin -D

Шаг 2: Изменитьwebpack.config.jsнастроить

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // ...
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'index.html',
            title: 'Vue3 + TS -> Web App'
        })
    ]
}

Уведомление: при настройке динамического заголовка веб-страницы необходимо установить<title>Измените содержимое ярлыка на<%= htmlWebpackPlugin.options.title %>

сервер разработки

После каждого пакета вам нужно вручную нажать, чтобы сгенерироватьindex.htmlЧтобы увидеть эффект, вы можете позволитьwebpackБудет ли упакованный файл автоматически открываться в браузере?

Шаг 1: Установите зависимости

npm install webpack-dev-server -D

Шаг 2: Изменитьwebpack.config.jsнастроить

module.exports = {
    // ...
    devServer: {
        port: 3000,
        hot: true,
        open: true,
        contentBase: '../dist'
    },
    // ...
}

Очистить пак-файлы

Если упакованный файл добавленhash, то каждый раз файл, сгенерированный упаковкой, будетdistСохранение каталога, мы можем использовать этот плагин, чтобы помочь нам очистить предыдущие файлы упаковки перед каждой упаковкой.

Шаг 1: Установите зависимости

npm install clean-webpack-plugin -D

Шаг 2: Изменитьwebpack.config.jsнастроить

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    // ...
    plugins: [
        // ...
        new CleanWebpackPlugin()
    ]
}

Установить переменные среды

Существует несколько распространенных способов установки переменных среды:

  • императив
  • Профиль
  • Создать файл .env
  • cross-env

мы начинаем сcross-envспособ установить переменные среды, потому что его можно установить на терминалах

Шаг 1: Установите зависимости

npm install cross-env -D

Шаг 2: Изменитьpackage.jsonнастроить

{
    // ...
    "scripts": {
        "webpack": "cross-env NODE_ENV=development webpack"
    }
    // ...
}

Упаковка по среде

В нашей обычной разработке проектов обычно есть: среда разработки, тестовая среда и производственная среда. Какой файл пакета подходит для среды разработки? Подходит для тестовой и производственной среды? Имея в виду эти вопросы, давайте настроим пакет для нескольких сред.

Упаковать и сжать

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

  • компрессияhtmlдокумент

    Исправлятьwebpack.config.jsнастроить

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {
        // ...
        plugins: [
            new HtmlWebpackPlugin({
                // ...
    +            minify: {
    +                collapseWhitespace: true, // 去掉空格
    +                removeComments: true // 去掉注释
    +            }
            }),
            // ...
        ]
    }
    
  • компрессияcssдокумент

    Шаг 1: Установите зависимости

    npm install mini-css-extract-plugin optimize-css-assets-webpack-plugin -D
    

    Шаг 2: Изменитьwebpack.config.jsдокумент

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
    
    module.exports = {
        // ...
        module: {
            rules: [
                // ...
                {
                    test: /\.css$/,
                    use: [
    +                   MiniCssExtractPlugin.loader,
                        'css-loader'
                    ]
                },
                {
                    test: /\.less$/,
                    use: [
    + 					MiniCssExtractPlugin.loader,
                        'css-loader',
                        'less-loader'
                    ]
                },
                // ...
            ]
        },
        plugins: [
            // ...
            new OptimizeCssAssetsWebpackPlugin(),
            new MiniCssExtractPlugin({
                filename: 'css/[name].css'
            })
        ]
    }
    

    Уведомление:purgecss-webpack-pluginиспользуется для очистки бесполезныхCSS

  • компрессияjsдокумент

    Шаг 1: Установите зависимости

    npm install terser-webpack-plugin -D
    

    Шаг 2: Изменитьwebpack.config.jsдокумент

    const TerserWebpackPlugin = require('terser-webpack-plugin');
    
    module.exports = {
        // ...
        optimization: {
            minimize: true,
            minimizer: [
                new TerserWebpackPlugin()
            ]
        },
        // ...
    }
    

    Уведомление:uglifyjs-webpack-pluginСжатие не поддерживаетсяES6синтаксический код

  • Сжать изображение

    Шаг 1: Установите зависимости

    npm install image-webpack-loader -D
    

    Шаг 2: Изменитьwebpack.config.jsдокумент

    module.exports = {
        // ...
        module: {
            rules: [
                // ...
                {
                    test: /\.(jpg|png|jpeg|gif|bmp)$/,
                    use: [
                        {
                            loader: 'url-loader',
                            options: {
                                limit: 1024,
                                fallback: {
                                    loader: 'file-loader',
                                    options: {
                                        name: '[name].[ext]'
                                    }
                                }
                            }
                        },
                        {
                            loader: 'image-webpack-loader',
                            options: {
                                mozjpeg: {
                                    progressive: true,
                                },
                                optipng: {
                                    enabled: false,
                                },
                                pngquant: {
                                    quality: [0.65, 0.90],
                                    speed: 4
                                },
                                gifsicle: {
                                    interlaced: false,
                                },
                                webp: {
                                    quality: 75
                                }
                            }
                        }
                    ]
                },
                // ...
            ]
        },
        // ...
    }
    

    Уведомление: во время установкиimage-webpack-loaderПри зависимости используйтеcnpmУстановить. использоватьnpmУстановка сообщит об ошибке:

    Module build failed (from ./node_modules/image-webpack-loader/index.js):
    Error: Cannot find module 'gifsicle'
    

Интеграция TypeScript

TypeScriptЭто обязательный навык для фронтенд-инженеров.Vue3Исходный код всех примененийTSпереписать. Поэтому его необходимо освоить и гибко применять в реальных проектах. Некоторые основные концепции в нем должны быть освоены: дженерики, перечисления, интерфейсы, классы, функции и т. д.

Среда конфигурации

Шаг 1: Установите зависимости

npm install typescript ts-loader -D

Шаг 2: Изменитьwebpack.config.jsдокумент

module.exports = {
    // ...
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: [
                    'ts-loader'
                ]
            },
            // ...
        ]
    },
    // ...
}

Шаг 3: Инициализацияtsconfig.jsonдокумент

tsc --init

Важный контент

  • Дженерики
  • интерфейс
  • функция
  • ...

Идентифицировать файлы .vue

Шаг 1: Установите зависимости

npm install vue@next -S
npm install vue-loader@next @vue/compiler-sfc

Уведомление:Vue2.xустановлен, когдаvue-template-complier

Шаг 2: Изменитьwebpack.config.jsдокумент

const { VueLoaderPlugin } = require('vue-loader/dist/index');

module.exports = {
    // ...
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: [
                    'vue-loader'
                ]
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin()
    ]
}

третий шаг:index.jsимпортируется в файлVue

// index.js
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app')

новыйApp.vueдокумент

// App.vue
<template>
    <div>
        <div>解析Vue文件了哟~</div>
        <p>{{name}}</p>
    </div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
    setup() {
        const name = ref('txm')

        return {
            name
        }
    }
})
</script>

Уведомление:defineComponentпросто использоватьVue3хорошие подсказки по грамматике

Composition API

Vue3кReact Hooksвдохновленный предыдущимoptions APIпереписать как函数式API, также удобно в значительной степени развязать кодtree-shaking, чтобы повысить скорость повторного использования кода. несмотря на то чтоVue2серединаMixinИзвлечение общего логического кода может быть выполнено, ноMixinЕсть также следующие недостатки: конфликты имен, методы и вычисляемые свойства с одинаковыми именами будут переопределены, жизненные циклы с теми же именами будут выполняться иmixinВыполнить сначала и так далее.

чаще используетсяComposition APIимеют:

  • реактивный, ссылка, эффект, просмотр, вычисление, жизненный цикл, функция h, toRefs и т. д. не перечислены один за другим

Для получения более подробной информации, пожалуйста, обратитесь к чтениюAPI композиции Vue

Отзывчивая система

все знаютVue2.xВ основе отзывчивости лежит использованиеObject.definePropertyзахватить каждое свойство объектаgetterа такжеsetter, при получении свойства сделать依赖收集, при обновлении свойств触发更新.

Vue2.xСредняя отзывчивость и методы:defineReactive

// src\core\observer\index.js

if (Array.isArray(value)) {
   this.observeArray(value)
} else {
   this.walk(value)
}
// 处理对象
walk (obj: Object) {
   const keys = Object.keys(obj)
   for (let i = 0; i < keys.length; i++) {
      defineReactive(obj, keys[i])
   }
}
// 处理数组
observeArray (items: Array<any>) {
   for (let i = 0, l = items.length; i < l; i++) {
      observe(items[i])
   }
}

export function defineReactive (
  obj: Object,
  key: string,
  val: any,
  customSetter?: ?Function,
  shallow?: boolean
) {
  const dep = new Dep()

  let childOb = !shallow && observe(val)
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      const value = getter ? getter.call(obj) : val
      if (Dep.target) {
        dep.depend() // 收集依赖
        if (childOb) {
          childOb.dep.depend()
          if (Array.isArray(value)) {
            dependArray(value)
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      const value = getter ? getter.call(obj) : val
      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
      childOb = !shallow && observe(newVal)
      dep.notify() // 通知更新
    }
  })
}

Из приведенных выше основных принципов видно, что при обработке数组а также对象судите и разбирайтесь с ними отдельно. Если данные представляют собой многоуровневую структуру, они будут выполнены, как только появятся.递归Манипуляции и перехват каждого свойства объекта плохо влияют на производительность.

  • СуммироватьVue2.xНесколько недостатков на реактивном уровне:
    1. свойство объекта新增а также删除Невозможно обнаружить -> Обходной путь:Vue.$setа такжеVue.delete()
    2. изменить массив索引а такжеlengthСвойство не может быть обнаружено -> Решение:splice

Vue3это использоватьProxyкак ядро ​​лежащего в основе отзывчивогоAPI, исходный код выглядит следующим образом:

// packages\reactivity\src\reactive.ts

function createReactiveObject(
  target: Target,
  isReadonly: boolean,
  baseHandlers: ProxyHandler<any>,
  collectionHandlers: ProxyHandler<any>
) {
  const proxy = new Proxy(
    target,
    targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
  )
  return proxy
}

createReactiveObjectметод является основным методом создания отзывчивости, можно увидеть, чтоProxyНепосредственное прослушивание всего объекта не имеет дело с массивами и объектами по отдельности.

Уведомление:изучениеVue3Когда исходный код, его нужно освоить заранееSet,WeakSet,Map,WeakMap,ReflectЖдатьES6Синтаксис для новых функций.

новые особенности

Vue3Он также предоставляет разработчикам несколько новых встроенных компонентов:Fragment,Suspense,Teleport

Интеграция Vue-маршрутизатора

основное использование

Шаг 1: Установите зависимости

npm install vue-router@4 -S

Шаг 2: СоздайтеHome.vueа такжеMe.vueдокумент

// Home.vue
<template>
    <div>
        首页
    </div>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
    name: 'Home'
})
</script>


// Me.vue
<template>
    <div>
        我的页面
    </div>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
    name: 'Me'
})
</script>

Шаг 3: Создайтеrouter.jsдокумент

import { createRouter, createWebHistory } from 'vue-router';
import Home from './Home.vue';
import Me from './Me.vue';

const routerHistory = createWebHistory();

const router = createRouter({
    history: routerHistory,
    routes: [
        {
            path: '/home',
            name: 'Home',
            component: Home
        },
        {
            path: '/me',
            name: 'Me',
            component: Me
        }
    ]
})

export default router;

Шаг 4: Изменитьindex.jsдокумент

// index.js
import { createApp } from 'vue';
import App from './App.vue';
+ import router from './router.js';

createApp(App).use(router).mount('#app')

можно увидеть и оригинальноVue2.xИспользование маршрутизации в

Интеграция Vuex

основное использование

Шаг 1: Установите зависимости

npm install vuex@next -S

Шаг 2: Создайтеstore.jsдокумент

import { createStore } from 'vuex';

const store = createStore({
    state: {
        name: 'vuex'
    },
    getters: {},
    actions: {},
    mutations: {},
    modules: {}
})

export default store;

Шаг 3: Изменитьindex.jsдокумент

import { createApp } from 'vue';
import App from './App.vue';
import router from './router.js';
+ import store from './store.js';

createApp(App).use(router).use(store).mount('#app')

Шаг 4: вApp.vueполучено вvuexданные в

<template>
    <div>
        <!-- ... -->
        <p>获取vuex里面的数据{{count}}</p>
        <!-- ... -->
    </div>
</template>
<script>
import { defineComponent, computed } from 'vue';
import { useStore } from 'vuex';
export default defineComponent({
    setup() {
        const store = useStore();
        const count = computed(() => store.state.count)

        return {
            count
        }
    }
})
</script>

Уведомление:использоватьcomputedпакет изstoreДанные, полученные в данных, могут обеспечить оперативность данных

Если не знакомVue3Для основного использования вы можете обратиться к этому основному введению.Быстро освоить разработку сегментов семейства Vue3

Интегрировать Вант

Шаг 1: Установите зависимости

npm install vant@next -S

Внедрить по требованию

Шаг 1: Установите зависимости

npm i babel-plugin-import ts-import-plugin -D

Шаг 2. Измените конфигурацию

JS-версия

// babel.config.js
module.exports = {
  plugins: [
    [
      'import',
      {
        libraryName: 'vant',
        libraryDirectory: 'es',
        style: true,
      },
      'vant',
    ],
  ]
};

ТС версия

const tsImportPluginFactory = require('ts-import-plugin');
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: [
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
              getCustomTransformers: () => ({
                before: [
                  tsImportPluginFactory({
                    libraryName: 'vant',
                    libraryDirectory: 'es',
                    style: (name) => `${name}/style/less`,
                  }),
                ],
              }),
              compilerOptions: {
                module: 'es2015',
              },
            }
          },
        ],
        exclude: /node_modules/
      },
      // ...
    ],
  }
};

Адаптация макета рем

Шаг 1: Установите зависимости

npm install lib-flexible -S
npm install postcss-pxtorem -D

Шаг 2: Добавьте.postcssrc.jsдокумент

module.exports = {
    plugins:{
        // autoprefixer: {
        //     browsers: ['Android >= 4.0', 'iOS >= 8']
        // },
        'postcss-pxtorem': {
            // rootValue: 37.5, // Vant 官方根字体大小是 37.5
            rootValue({file}) {
                return file.indexOf('vant') !== -1 ? 37.5 : 75
            },
            propList: ['*'],
            selectorBlackList: ['.norem'] // 过滤掉.norem-开头的class,不进行rem转换
        }
    },
}

Уведомление:browsersПараметры должны быть настроены вpackage.json, иначе при упаковке будет предупреждение

// package.json
{
  // ...
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead",
    "Android >= 4.0",
    "iOS >= 8"
  ]
}

Шаг 3. Знакомство и использование

// index.js
import { createApp } from 'vue';
+ import 'lib-flexible/flexible';
import App from './App.vue';
import router from './router.js';
import store from './store.js';

createApp(App).use(router).use(store).mount('#app')
// Home.vue
<template>
  <div>
    首页
    <v-button plain hairline type="primary">细边框按钮</v-button>
    <v-button plain hairline type="primary">细边框按钮</v-button>
  </div>
</template>
<script>
import { defineComponent, ref } from "vue";
import { Button } from "vant";
export default defineComponent({
  name: "Home",
  components: {
    "v-button": Button
  }
});
</script>

оптимизация

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

Каноническая структура каталогов

использовать вышеWebpack5После настройки каждой среды стандартизируйте структуру каталогов проекта.Стандартная структура каталогов проекта выглядит следующим образом:

tree -I "node_modules"
├─dist
│  ├─css
│  └─js
|  |-favicon.ico
|  |-index.html
├─node_modules
├─public
|  |-index.html
|  |-favicon.ico
└─src
|  ├─api
|  ├─components
|  ├─hooks
|  ├─router
|  ├─store
|  ├─utils
|  └─views
|  |-App.vue
|  |-main.ts
|-.gitigore
|-babel.config.js
|-package.json
|-shims-vue.d.ts
|-tsconfig.json
|-webpack.config.js

Посмотрите, похожа ли эта структура каталогов наVueКаталог сгенерированных проектов строительных лесов

Уведомление:из-заTypeScriptмогу только понять.tsфайл, не могу понять.vueфайл, поэтому вам нужно создать суффикс в корневом каталоге проекта как.d.tsдокумент;

// shims-vue.d.ts

declare module '*.vue' {
    import { ComponentOptions } from 'vue';
    const componentOptions: ComponentOptions;
    export default componentOptions;
}

Советы по упаковке

Шаг 1: Установите зависимости

npm install friendly-errors-webpack-plugin node-notifier -D

Шаг 2: Изменитьwebpack.config.jsдокумент

const path = require('path');
+ const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
+ const notifier = require('node-notifier');
+ const icon = path.join(__dirname, 'public/icon.jpg');
module.exports = {
  // ...
  plugins: [
    new FriendlyErrorsWebpackPlugin({
      onErrors: (severity, errors) => {
        notifier.notify({
          title: 'webpack 编译失败了~',
          message: `${severity} ${errors[0].name}`,
          subtitle: errors[0].file || '',
          icon,
        });
      },
    }),
    // ...
  ],
};

Анализ размера файла пакета

Шаг 1: Установите зависимости

npm install webpack-bundle-analyzer -D

Шаг 2: Изменитьwebpack.config.jsдокумент

+ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
  // ...
  plugins: [
    new BundleAnalyzerPlugin(),
    // ...
  ],
};

Шаг 3: Изменитьpackage.jsonдокумент

{
    "scripts": {
     // ...
    "analyzer": "webpack --progress"
  },
}

консольное выполнениеnpm run analyzerСистема автоматически запускает HTTP-сервер для упакованного отчета, если вы не хотите запускать его каждый раз, вы можете сгенерироватьstats.jsonФайл просматривается, когда вы хотите просмотреть его позже.

+ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
  // ...
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'disabled',
      generateStatsFile: true
    }),
    // ...
  ],
};

package.jsonв файлеscriptsДобавьте в поле новую команду:

{
    "scripts": {
     // ...
+    "analyzers": "webpack-bundle-analyzer --port 3000 ./dist/stats.json"
  },
}

С помощью отчета об упаковке вы можете интуитивно узнать, какие зависимые пакеты являются большими, и можете вносить целевые изменения.

Скорость упаковки

Этот плагин умеет наглядно и интуитивно отображать в консоли время, потраченное на упаковку каждой зависимости.

Шаг 1: Установите зависимости

npm install speed-measure-webpack5-plugin -D

Уведомление:Webpack5внутренняя конфигурацияspeed-measure-webpack-pluginУпаковка сообщит об ошибке

Шаг 2: Изменитьwebpack.config.js

const SpeedMeasureWebpack5Plugin = require('speed-measure-webpack5-plugin');
const smw = new SpeedMeasureWebpack5Plugin();

module.exports = smw({
	// options
})

Сузить пакет

исключить: исключить определенные файлы, аналогично черному списку include: какие файлы включены, аналогично белому списку

Если настроены оба, исключение имеет приоритет над включением.

const path = require('path');

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
        exclude: /node_modules/,
        include: path.resolve(__dirname, 'src')
      },
      // ...
    ],
  },
};

тайник

По умолчаниюbabel-loaderКэш можно настроить в другомloaderТоже хочу кеш, надо скачатьcache-loader

Шаг 1: Загрузите зависимости

npm install cache-loader -D

Шаг 2: Изменитьwebpack.config.jsдокумент

const path = require('path');

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
+            cacheDirectory: true
          },
        },
        // ...
      },
      {
        test: /\.css$/,
        use: ['cache-loader', 'style-loader', 'css-loader'],
      }
      // ...
    ],
  },
};

разное

  • resolve
  • external
  • optimization
  • так далее

Единая спецификация кода

Спецификация Unicode включает проверку кода, форматирование кода,gitПредварительная проверка, настройка редактора и т. д.

Eslint

ESLintявляется открытым исходным кодомJavaScriptинструмент проверки кода

  • новый.eslintrc.jsдокумент

    module.exports = {
      root: true, // 此项是用来告诉eslint找当前配置文件不能往父级查找
      env: {
        node: true, // 此项指定环境的全局变量,下面的配置指定为node环境
      },
      extends: ['plugin:vue/recommended', '@vue/prettier'],
      rules: {
        'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
        'vue/no-v-html': 'off',
      },
      parserOptions: {
        parser: 'babel-eslint',
        parser: 'babel-eslint',
        ecmaVersion: 7,
        sourceType: 'module',
        ecmaFeatures: {
          // 添加ES特性支持,使之能够识别ES6语法
          jsx: true,
        },
      },
      overrides: [],
    };
    
    
  • новый.eslintignoreдокумент

    # .eslintignore 不需要检查的文件
    
    src/assets
    src/icons
    public
    dist
    node_modules
    
    

Perttier

Prettierэто инструмент форматирования кода. иметь возможность форматировать наш код в соответствии с нашими правилами

  • новыйprettier.config.jsдокумент

    module.exports = {
      printWidth: 80,
      tabWidth: 2,
      useTabs: false,
      semi: false,
      singleQuote: true,
      quoteProps: 'as-needed',
      jsxSingleQuote: false,
      trailingComma: 'es5',
      bracketSpacing: true,
      jsxBracketSameLine: false,
      arrowParens: 'always',
      htmlWhitespaceSensitivity: 'ignore',
      vueIndentScriptAndStyle: true,
      endOfLine: 'lf',
    }
    

stylelint

stylelintможет помочь нам нормализоватьcssнаписано в последовательном стиле, уменьшая количество ошибок

  • новый.stylelintrc.jsдокумент

    module.exports = {
      extends: ['stylelint-config-recess-order', 'stylelint-config-prettier'],
    }
    

EditorConfig

  • новый.editorconfigдокумент

    root = true
    
    [*]
    charset = utf-8
    end_of_line = lf
    indent_size = 2
    indent_style = space
    insert_final_newline = true
    trim_trailing_whitespace = true
    
    [*.md]
    trim_trailing_whitespace = false
    

Настройка сообщений Git

Шаг 1: Установите зависимости

npm install -g commitizen cz-conventional-changelog
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc

После установки его можно использовать напрямуюgit czзаменитьgit commit

yarn add husky @commitlint/config-conventional @commitlint/cli -D
  • commitlint: ответственный заcommit messageпроверка формата
  • husky: Отвечает за предоставление более простого в использованииgit hook

Шаг 2: Создайте корневой каталогcommitlint.config.js

echo 'module.exports = {extends: ["@commitlint/config-conventional"]};' > ./commitlint.config.js

Уведомление:использоватьUTF-8формат, иначеhuskyсообщит об ошибке

третий шаг:package.jsonимпортируется в файлhusky

"husky": {
    "hooks": {
      "commit-msg": "commitlint -e $GIT_PARAMS"
    }
}

Шаг 4: Используйте

  • git add .
  • git cz выберите и введите
  • git push -u origin имя ветки может

Автоматизированная публикация

let client = require('scp2');
const ora = require('ora');
const chalk = require('chalk');
const spinner = ora(chalk.green('正在发布到服务器...'))

spinner.start()
client.scp('./dist', { // 本地打包的路径
    'host': 'xxx.xxx.x.xxx', // 服务器的IP地址
    'post': '22', // 服务器的IP地址
    'username': 'xxxx', // 用户名
    'password': '*****', // 密码
    'path': '/opt/stu_app_website' // 项目需要部署到服务器的位置
}, err => {
    spinner.stop();
    if(!err) {
        console.log(chalk.green('项目发布完毕'))
    } else {
        console.log('err', err)
    }
})

Реальный проект компании подключенCI/CDАвтоматизированный тестовый выпуск

Суммировать

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