Vuejs Tribulation Series II: краткий анализ конфигурации в рамках самого полного проекта vue-cli

Командная строка JavaScript Vue.js Webpack
Vuejs Tribulation Series II: краткий анализ конфигурации в рамках самого полного проекта vue-cli

简析vue-cli快速搭建项目下的配置

Вторая статья в серии Vuejs Robbery основана на солидных базовых знаниях Vuejs и WebPack и быстро создает проект через леса Vuue-Cli. Эта статья разоблачит конфигурации файлов и использует под проектом один за другим.

Советы: эта статья в основном объединила конфигурацию под проектом быстрого строительства CLI CLI CLI. В основном, ключевой код конфигурации всех файлов, в следующем отделке автора через время работы, очень сложно, я надеюсь, что друзья будут Дайте адрес склада. ★ (звезда):

"https://github.com/WeideMo/vuecli-webpack-configs"

Кроме того, если в процессе использования vue-разработки возникнут какие-то необъяснимые проблемы, вы также можете обратиться к моей предыдущей статье.Vuejs渡劫系列一:日常开发中必须掌握的细节(keng), Я считаю, что вы также получите много.

Подготовить

Установить инструменты командной строки (CLI)

Vue.js предоставляет очень удобный инструмент командной строки в глобальной зависимости после установки, сможет легко в любом уголке файловой системы с помощью скаффолдинга создать и запустить полосу с тепловой перегрузкой, и может быть использован для производства статической проверки при сохранении конфигурации сборки среды проекта с помощью следующей команды:

# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖
$ cd my-project
$ npm install
$ npm run dev

Посмотреть результаты установки

vue -V
2.8.1

Состав проекта

Структура каталогов

├── build
│   ├── build.js
│   ├── check-versions.js
│   ├── dev-client.js
│   ├── dev-server.js
│   ├── utils.js
│   ├── vue-loader.conf.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   ├── webpack.test.conf.js
│   └── webpack.prod.conf.js
├── config
│   ├── dev.env.js
│   ├── index.js
│   ├── test.env.js
│   └── prod.env.js
├── node_modules    
├── src
│   ├── App.vue
│   ├── assets
│   │   └── img.png
│   ├── components
│   │   └── Hello.vue
│   └── main.js
├── static
├── test
│   └── unit
│   │   ├─── coverage
│   │   ├─── specs
│   │   ├─── .eslintrc
│   │   ├─── index.js
│   │   └── karma.conf.js
│   └── e2e
├── .babelrc
├── .editorconfig
├── .gitignore
├── .postcssrc.js
├── index.html
├── package.json
└── README.md

/build

build.js

в исполненииnpm run buildКогда скрипт js выполняется, он в основном загружает конфигурацию веб-пакета в производственной среде и перестраивает сжатый проект, используемый в производственной среде, в соответствии с конфигурацией веб-пакета.Окончательный файл ресурсов будет создан в корневом каталоге.distв файле.

check-version.js

Шаг проверки перед сборкой в ​​качестве процесса проверки перед сборкой пакета производственного проекта.

dev-client.js

require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')

hotClient.subscribe(function (event) {
  if (event.action === 'reload') {
    window.location.reload()
  }
})

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

dev-server.js

var app = express();
...
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
  log: false,
  heartbeat: 2000
})

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

utils.js

utils.jsВ основном это инструментальный метод, используемый для настройки веб-пакета ответа на внешний мир, включая предоставление статических путей ресурсов ресурсов во внешний мир:

exports.assetsPath = function (_path) {
  var assetsSubDirectory = process.env.NODE_ENV === 'production'
    ? config.build.assetsSubDirectory
    : config.dev.assetsSubDirectory
  return path.posix.join(assetsSubDirectory, _path)
}

Обеспечьте внешнюю настройку различных загрузчиков, таких как cssLoaders, css/postcss/less/sass/scss/stylus/styl и другие конфигурации предварительной или постобработки и т. д.:

  return {
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less'),
    sass: generateLoaders('sass', { indentedSyntax: true }),
    scss: generateLoaders('sass'),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')
}

vue-loader.conf.js

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

webpack.base.conf.js

Общий файл конфигурации для веб-пакета, т.е. независимо от средыtest,developещеproduction, всем нужно загрузить конфигурацию webpack, этот файл очень важен, а конфигурацию часто нужно модифицировать:

входной файл запись

entry: {
  app: './src/main.js',
  utils:['./src/assets/libs/jquery.js']
}

По умолчанию только приложение является записьюmain.js, utils — это пользовательская запись. Путем настройки нескольких файловых записей размер файла после сборки может быть уменьшен, а также он может взаимодействовать сCommonsChunkPluginПлагины для субподряда проектов.

выходной файл

Конфигурация конфига находится в файле config/index.js

output: {
  path: config.build.assetsRoot, //导出目录的绝对路径
  filename: '[name].js', //导出文件的文件名
  publicPath: process.env.NODE_ENV === 'production'? config.build.assetsPublicPath : config.dev.assetsPublicPath //生产模式或开发模式下html、js等文件内部引用的公共路径
}

разрешение синтаксического анализа файлов

В основном устанавливает способ разрешения модулей.

resolve: {
  extensions: ['.js', '.vue', '.json'], //自动解析确定的拓展名,使导入模块时不带拓展名
  alias: {   // 创建import或require引入时,文件使用的别名
    'vue$': 'vue/dist/vue.esm.js', 
    '@': resolve('src')
  }
}

который определен по умолчаниюvue$дляvue.esm.jsпсевдоним файла,@для/srcПсевдоним каталога через@/xxx.jsили@/xxx.vueВы можете быстро импортировать файлы.Обратите внимание, что только файлы .js и .vue в файле vue могут быть адресованы с помощью @, а файлы, такие как scss или меньше, использовать нельзя.@найти файлы.

Модуль механизма разрешения модуля

Этот модуль в основном используется для определения файлов с разными файловыми суффиксами, а также для определения того, какие загрузчики следует использовать для загрузки и анализа.В отличие от веб-пакета 1.x, исходныйloadersзаменяется наrules; Обратите внимание, что vue-cli по умолчанию уже оборудован для вас.vue,.js,img类,媒体类,字体类и т.д. разбор файла тем временем,.vueЕсли язык препроцессора, используемый в компоненте, должен быть<style>добавлено на ярлыкlangсвойства, такие как

<style lang="scss" scoped>
        body{
          background-color:#FFF;
        }
</style>

webpack.dev.conf.js

Комбинированная базовая конфигурация через метод слияния webpack.base.conf.js

var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
module.exports = merge(baseWebpackConfig, {})

Конфигурация модуля

module: {
  //通过传入一些配置来获取rules配置,此处传入了sourceMap: false,表示不生成sourceMap
  rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 
}

Здесь упоминается метод styleLoaders в utils.js, и автоматически сгенерированная конфигурация выглядит следующим образом.

exports.styleLoaders = function (options) {
   //定义输出的数组
  var output = []
  // 调用cssLoaders方法返回各类型的样式对象(css: loader)
  var loaders = exports.cssLoaders(options) 
  //循环遍历loaders
  for (var extension in loaders) {  
    //根据遍历获得的key(extension)来得到value(loader)
    var loader = loaders[extension] 
    output.push({     
      // 通过正则匹配判断各类型的样式文件,并生成test和对应loaders
      test: new RegExp('\\.' + extension + '$'), 
      use: loader
    })
  }
  return output
}

Приведенный выше код вызывает exports.cssLoaders(options), который в основном используется для реализации загрузчиков для различной предварительной обработки css Конкретная реализация выглядит следующим образом.

exports.cssLoaders = function (options) {
  options = options || {}

  var cssLoader = { 
    loader: 'css-loader',
    options: {  
      //生成环境下压缩文件
      minimize: process.env.NODE_ENV === 'production', 
      //根据参数是否生成sourceMap文件
      sourceMap: options.sourceMap  
    }
  }
  function generateLoaders (loader, loaderOptions) {  
    // 预置css-loader
    var loaders = [cssLoader] 
    // 如果参数loader存在
    if (loader) { 
      //如果配置的预处理需要,则push一个进入loaders数组
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, { 
          sourceMap: options.sourceMap
        })
      })
    }
    // 如果传入的options存在extract且为true
    if (options.extract) { 
      //通过使用ExtractTextPlugin插件分离js中引入的css文件
      return ExtractTextPlugin.extract({  
        use: loaders,  
        //没有被提取分离的使用vue-style-loader加载
        fallback: 'vue-style-loader' 
      })
    } else {
        //如果没有传入的options存在extract或为false时,统一使用vue-style-loader处理
      return ['vue-style-loader'].concat(loaders)
    }
  }
  return {  //返回css类型对应的loader组成的对象 generateLoaders()来生成loader
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less'),
    sass: generateLoaders('sass', { indentedSyntax: true }),
    scss: generateLoaders('sass'),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')
  }
}

Конфигурация плагина

plugins: [
  // 编译时配置的全局变量
  new webpack.DefinePlugin({ 
    //当前环境为开发环境
    'process.env': config.dev.env 
  }),
  //热重载插件
  new webpack.HotModuleReplacementPlugin(), 
  //不触发错误,即编译后运行的包正常运行
  new webpack.NoEmitOnErrorPlugin(), 
  //自动生成html文件
  new HtmlWebpackPlugin({  
    filename: 'index.html', //生成的文件名
    template: 'index.html', //模板
    inject: true
  }),
  //友好的错误提示
  new FriendlyErrorsPlugin() 
]

webpack.prod.conf.js

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

Судебная среда

  //判断环境,如果是testing的话,则加载test.env
var env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : config.build.env

Обработчик стиля загрузки

module: {
  //同样使用了utils.styleLoaders的方法处理,这里不赘述
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  //通过判断配置值,判断是否生产source-map
  devtool: config.build.productionSourceMap ? '#source-map' : false
  }

выходной файл

output: {
  //配置的生产资源路径
  path: config.build.assetsRoot,
  //生成的文件名,一般会生成入口名称.[hash].js,如app.7d0bcfcc47ab773ebe20834b27a0927a.js
  filename: utils.assetsPath('js/[name].[chunkhash].js'),
  //生成的异步文件块,一般是分配id.[hash].js,如0.app.7d0bcfcc47ab773ebe20834b27a0927a.js
  chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
}

Обратите внимание, что блок асинхронного файла здесь системаrouterВнизindex.jsВведенные в нем асинхронные компоненты генерируются автоматически, поэтому нам не нужно переименовывать эту часть файла, иначе это легко приведет к ошибкам файлового индекса и 404 ошибкам.

плагин

//这里定义全局环境为生产
new webpack.DefinePlugin({
    'process.env': env
  }),
//js压缩插件
new webpack.optimize.UglifyJsPlugin({
  compress: {
    //不显示警告
    warnings: false
  },
  //生产source-map
  sourceMap: true
}), 
//在css文件单独分离出来
new ExtractTextPlugin({
    //生成的文件名,一般会生成入口名称.[hash].css,如app.7d0bcfcc47ab773ebe20834b27a0927a.css
    filename: utils.assetsPath('css/[name].[contenthash].css')
  }),
  //css配置插件,可以提取并压缩css文件
new OptimizeCSSPlugin({
    cssProcessorOptions: {
      safe: true
    }
  }),
//CommonsChunkPlugin 公共块提取插件
 new webpack.optimize.CommonsChunkPlugin({
   //配置生成的文件名称:vendor
    name: 'vendor',
    minChunks: function (module, count) {
     //这里是默认的使用方法,将node_module引用到打包在一起
      return (
        //正则匹配
        module.resource &&
        /\.js$/.test(module.resource) &&
        module.resource.indexOf(
          path.join(__dirname, '../node_modules')
        ) === 0
      )
    }
  }),

Обратите внимание, что здесь поCommonsChunkPluginПлагин объединяет файлы пакетов, такие как vue, vuex и т. д., в js с именем: vendor и, наконец, генерирует аналогичный файл с именемvendor.7d0bcfcc47ab773ebe20834b27a0927a.js, Конечно, чтобы предотвратить каждое изменение хэша, упакованного приложением, что приводит к тому, что ресурсы не кэшируются, нам нужно добавитьmanifest, чтобы отдельно скомпилировать код среды выполнения в файл манифеста на случай, если хэш vendor.js будет меняться при каждой компиляции:

new webpack.optimize.CommonsChunkPlugin({
    name: 'manifest',
    chunks: ['vendor']
  }),

Иногда нам нужно упаковать третью библиотеку js, которую мы ввели в отдельный файл, если она называется utils.js, мы также можем использоватьCommonsChunkPluginОбрабатывать:

new webpack.optimize.CommonsChunkPlugin({
   names: ["utils"]
 })

Не забываем, что нам нужно добавить в него обработку манифеста, достаточно просто модифицировать существующий базис:

new webpack.optimize.CommonsChunkPlugin({
    name: 'manifest',
    chunks: ['vendor','utils']
  }),

Конечно, нам нужно добавить для него входной файл,

entry: {
  app: './src/main.js',
  utils:['./src/assets/libs/jquery.js'] //这里可以根据你自己需求增加其他三方库文件
}

другие плагины

Кроме того, есть другие плагины, такие какcompression-webpack-plugin, используемый для обработки сжатия на основе регулярного сопоставления;webpack-bundle-analyzerЕго можно оптимизировать под размер вашей сумки и т. д., и вы можете изучить его самостоятельно.

/config

определение переменной среды

В этом разделе определяются глобальные переменные среды для производства, разработки и тестирования, чтобы настроить использование различных конфигураций веб-пакетов в разных средах путем определенияNODE_ENVПеременная:

var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
})

/node_modules

Третий пакет, установленный npm

Подсчитано, что студенты, использовавшие npm, не будут здесь незнакомы, а те, кто размещен здесь, прошли мимо нас.npm installКласс стороннего инструмента, установленный методом, может быть быстро введен нами через ключевое слово require.

/test

unit

Этот файл в основном содержит модульные тесты для проектов, созданных с помощью vue-cli, что позволяет пользователям быстро писать модульные тесты на уровне компонентов и использовать их в корневом каталоге.npm run unitКоманда для модульного тестирования кода:

index.js

const testsContext = require.context('./specs', true, /\.spec$/)
testsContext.keys().forEach(testsContext)

Требуя текущий каталогspecsИспользуйте файл прецедентов в модульном тесте .vue

const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
srcContext.keys().forEach(srcContext)

Здесь определяется каталог исходного файла для чтения, и первая строка читается обычным способом.../../srcвниз, кромеmain.jsДля прохождения других файлов, если нам нужно только модульное тестирование локальных файлов, мы можем сузить диапазон путей, например, нам нужно только компоненты модульного тестирования в src:

const srcContext = require.context('../../src/components', true, /^\.\/(?!main(\.js)?$)/)

karma.conf.js

Из-за модульного теста, оснащенного vue-cli, используется karma.js Здесь нам нужно использовать только конфигурацию по умолчанию, которую обычно не нужно менять.

specs

Вот тестовый пример断言раздел, написав*.spec.jsЧтобы сделать утверждения логических частей компонентов для достижения эффекта модульного тестирования, ниже приведен пример создания экземпляра компонента и утверждения текста представления в компоненте:

import Vue from 'vue'
import Hello from '@/components/Hello'

describe('Hello.vue', () => {
  it('should render correct contents', () => {
    const Constructor = Vue.extend(Hello)
    const vm = new Constructor().$mount()
    expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome to Your Vue.js App')
  })
})

coverage

юнит-тесты на карму при предоставленииcoverage RateТо есть покрытие юнит-тестами будет описывать полноту ваших юнит-тестов по разным файлам, от количества строк до количества функций.npm run unitКогда закончите, просмотритеcoverage\lcov-report\index.htmlРезультаты покрытия можно увидеть:

简析vue-cli快速搭建项目下的配置

Корневая директория

.babelrc

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-runtime"],
  "env": {
    "test": {
      "presets": ["env", "stage-2"],
      "plugins": ["istanbul"]
    }
  }
}

Сформулировал конфигурацию babel, определил загруженные плагины и плагины, необходимые для запуска теста.istanbul

.editorconfig

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

Определен формат редактирования: используйтеutf-8кодировка, пробелspace, отступ строки两个字符В конце также вставляется новая строка, которая обрабатывает символы пробела в начале и в конце символа.

.gitignore

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

.postcssrc.js

Поскольку новая версия webpack оснащена загрузчиками postcss, она будет проверять, существует ли файл конфигурации в корневом каталоге.plugins, чтобы настроить то, что вам нужно, вот что я использовалautoprefixerа такжеpostcss-spritesКонфигурация

module.exports = {
  "plugins": {
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {},
    "postcss-sprites":{
      // stylesheetPath: './css',
      spritePath: './css/images/',
      filterBy: function(image) {
        // Allow only png files
        if (!/\.png$/.test(image.url)) {
          return Promise.reject();
        }

        return Promise.resolve();
      }
    }
  }
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>uvoice</title>
  </head>
  <body>
    <section class="container" id="J_container">
    </section>
    <!-- built files will be auto injected -->
  </body>
</html>

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

package.json

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

README.md

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

Суммировать

Эта бита действительно немного длинная.По оценкам, здесь не так много студентов, но это действительно авторская работа.По оценкам, у студентов, прочитавших полный текст, должно быть новое понимание проекта, сгенерированного vue -cli scaffolding.При этом у меня тоже будет ощущение своего первого исследования,то есть слишком много тонкостей в проекте.Когда действительно разберешься,то вдруг почувствуешь пропасть между собой и дизайном архитектуры проекта .Конечно,эта статья только для vue- Конфигурация cli прочитана.В следующей статье будет немного галантереи,и я действительно пройдусь по всему проекту vue-cli.Надеюсь вы и дальше будете платить внимание ко мне.