Продвинутый высокооплачиваемый интерфейс, обязательный к просмотру — Webpack

опрос

"предисловие"

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

"Подать жалобу:"Упоминание вебпака действительно грустное и слезливое.Помню, когда только вышла версия 1.0 вебоака, я следил за документацией и просматривал пункты конфигурации и ту же конфигурацию, что и на официальном сайте, но я не мог понять всевозможные ошибки. время, это был действительно веб-пакет, когда я только что сделал внешний интерфейс.От входа до отказа, особенно сейчас, когда вы проходите собеседование на старшие позиции переднего плана, вы обнаружите, что интервьюеры любят спрашивать о вещах, связанных с веб-пакетом.Я видел несколько крупных фабрик берут интервью у самих себя и начинают использовать webpack после своих интервью, ха-ха(Может быть, это потому, что у меня есть некоторый опыт архитектуры в моем резюме)

"Изменять:"На данный момент webpack дошел до версии 4.0.Оптимизированы официальные документы и многое другое.Теперь он проще в использовании и различные скаффолдинги в принципе помогают нам настроить webpack,но это не значит что нам не нужно знать принцип работы webpack потому что мы стоим с точки зрения архитектуры интерфейса.Необходимо уметь анализировать пакет автоматизации интерфейса.В то же время, как промежуточный и продвинутый интерфейс, также необходимо твердо усвоить фронтальные инструменты.

1 Что такое вебпак

Webpack — это автоматизированное решение для упаковки, которое также можно понимать как сборщик модулей. Это помогает нам анализировать структуру проекта, находить модули JavaScript и другие языки расширения (Scss, TypeScript и т. д.), которые браузеры не могут запускать напрямую, и упаковывать их в подходящие форматы для использования браузерами.

Если нет веб-пакета, сколько нам придется вручную обрабатывать вышеперечисленные вещи

2 Каковы общие конфигурации веб-пакета

  1. Entry: Entry, первый шаг в выполнении сборки Webpack начнется с Entry, который можно абстрагировать во входные данные.
  2. Вывод: выведите результат после того, как Webpack пройдет серию обработок и получит окончательный желаемый код.
  3. режим: предоставляет параметр конфигурации режима, который указывает веб-пакету использовать встроенные оптимизации для соответствующего режима.
  4. Модуль: модуль, все является модулем в Webpack, а модуль соответствует файлу.
  5. Чанк: блок кода, фрагмент состоит из нескольких модулей для слияния и разделения кода.
  6. Загрузчик: преобразователь модулей, который используется для преобразования исходного содержимого модуля в новое содержимое по мере необходимости.
  7. Плагин: плагин расширения, который внедряет логику расширения в определенное время в процессе сборки Webpack, чтобы изменить результат сборки или сделать то, что вы хотите.

3 рабочий процесс веб-пакета

  1. Разбор параметров: чтение и объединение параметров из файлов конфигурации и операторов оболочки для получения окончательных параметров.
  2. Найдите файл записи: начните с модуля, настроенного в записи, для рекурсивного разрешения всех модулей, от которых зависит запись.
  3. Вызовите загрузчик для компиляции файла: каждый раз, когда модуль будет найден, соответствующее правило преобразования будет найдено в соответствии с настроенным загрузчиком.
  4. Пройдите AST и соберите зависимости: после преобразования модуля проанализируйте модуль, от которого зависит текущий модуль.
  5. Генерация фрагмента: эти модули будут сгруппированы в единицы Записи, Запись и все ее зависимые Модули разделены на группу, которая является Чанком.
  6. Выходной файл: наконец, Webpack преобразует все фрагменты в выходной файл.

Студенты, которые хотят увидеть исходный код конкретного принципа компиляции веб-пакетапортал

4 Общая конфигурация загрузчика и рабочий процесс

// webpack.config.js
module.exports = {
  module: {
    rules: [
     {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      { test: /\.js$/, use: 'babel-loader' },
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          { loader: 'postcss-loader' },
        ]
      }
    ]
  }
};

"Рабочий процесс загрузчика"

  1. Загрузчик модуля настраивается в webpack.config.js;
  2. Когда встречается соответствующий файл модуля, запускается загрузчик модуля;
  3. Загрузчик принимает источник, представляющий содержимое файла модуля;
  4. Загрузчик использует ряд API-интерфейсов, предоставляемых webapck, для преобразования исходного кода и получения результата;
  5. Возвращайте или передайте результат следующему загрузчику, пока обработка не будет завершена.

Взгляните на пример less-loader (о конкретной реализации загрузчика см.Пример официального сайта)

let less = require('less');
module.exports = function (source) {
    const callback = this.async();
    //this.async() 返回一个回调函数,用于异步执行
    less.render(source, (err, result) => {
    //使用less处理对应的less文件的source
        callback(err, result.css);
    });
}

5 распространенных конфигураций плагинов и простые принципы

"Знакомство с общими плагинами проекта"

  1. extract-text-webpack-plugin

По умолчанию webpack упаковывает css как модуль в чанк.

const ExtractTextPlugin = require('extract-text-webpack-plugin');
new ExtractTextPlugin({
    filename: 'css/[name].css',
})
{
    test: /\.css$/,
    use: ExtractTextPlugin.extract({
        use: ['css-loader','postcss-loader','less-loader'],
        fallback: 'vue-style-loader',  #使用vue时要用这个配置
    })
},
  1. html-webpack-плагин Этот плагин очень важен.Первой функцией является создание файлов HTML-страницы в вашем выходном каталоге, а второй функцией является автоматическое добавление фрагментов, упакованных webpack, в этот HTML.
const HtmlPlugin = require('html-webpack-plugin')
new HtmlPlugin({
    filename: 'index.html',
    template: 'pages/index.html'
}
  1. определить плагин определить глобальные константы
new webpack.DefinePlugin({
    'process.env': {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV)
    },
    PRODUCTION: JSON.stringify(PRODUCTION),
    APP_CONFIG: JSON.stringify(appConfig[process.env.NODE_ENV]),
}),
  1. UglifyJsПлагин сжатие js
new webpack.optimize.UglifyJsPlugin()

Примечание: webpack4 удалил этот плагин, используйте вместо него оптимизацию.минимизировать

  1. CommonsChunkПлагин CommonsChunkPlugin в основном используется для извлечения сторонних библиотек (таких как jQuery) и общедоступных модулей (обычных js и css), которые часто используются в многостраничных приложениях для создания общедоступных фрагментов и предотвращения повторных ссылок.
{
    entry: {
        vendor: 'index.js'
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: ['vendor','runtime'],
            filename: '[name].js'
        }),
    ]
}

Примечание: webpack4 удалил этот плагин, используйте вместо него оптимизацию.SplitChunks.

"Простой принцип"

Плагин похож на функцию, встроенную в производственную линию, обрабатывающую ресурсы на производственной линии в определенное время. Webpack использует Tapable для организации этой сложной производственной линии. В процессе компиляции кода вебпак вызовет серию событий Tapable hook, что делает плагин, так это находит соответствующий хук и вешает на него свою задачу, то есть событие регистрации.Таким образом, когда вебпак построен, подключаемый модуль регистрируется. Событие будет выполнено при срабатывании хука.

Плагин webpack состоит из следующего:

  • Именованная функция JavaScript.
  • Определите метод применения в прототипе функции плагина.
  • Указывает обработчик событий, привязанный к самому веб-пакету.
  • Обрабатывать внутренние данные конкретного экземпляра веб-пакета.
  • Вызовите обратный вызов, предоставленный веб-пакетом, после завершения функции.

"Пример пользовательского плагина"(Для получения дополнительной информации, пожалуйста, посетите официальный сайтСоздать плагин)

// 一个 JavaScript 命名函数。
function MyExampleWebpackPlugin() {

};

// 在插件函数的 prototype 上定义一个 applyметод. MyExampleWebpackPlugin.prototype.apply = функция (компилятор) { // Указываем обработчик событий для подключения к самому веб-пакету. компилятор.plugin('webpacksEventHook', function(compilation /* Обработка данных, специфичных для внутреннего экземпляра webpack. */, callback) { console.log("Это пример плагина!!!");

// 功能完成后调用 webpack 提供的回调。
callback();

}); };

скопировать код

6 Что делать, если скорость упаковки webpack слишком низкая

  1. Уменьшите объем компиляции и сократите ненужную работу по компиляции, то есть используются модули, mainFields, noParse, include, exclude, alias.
const resolve = dir => path.join(__dirname, '..', dir);
resolve: {
    modules: [ // 指定以下目录寻找第三方模块,避免webpack往父级目录递归搜索
        resolve('src'),
        resolve('node_modules'),
        resolve(config.common.layoutPath)
    ],
    mainFields: ['main'], // 只采用main字段作为入口文件描述字段,减少搜索步骤
    alias: {
        vue$: "vue/dist/vue.common",
        "@": resolve("src") // 缓存src目录为@符号,避免重复寻址
    }
},
module: {
    noParse: /jquery|lodash/, // 忽略未采用模块化的文件,因此jquery或lodash将不会被下面的loaders解析
    // noParse: function(content) {
    //     return /jquery|lodash/.test(content)
    // },
    rules: [
        {
            test: /\.js$/,
            include: [ // 表示只解析以下目录,减少loader处理范围
                resolve("src"),
                resolve(config.common.layoutPath)
            ],
            exclude: file => /test/.test(file), // 排除test目录文件
            loader: "happypack/loader?id=happy-babel" // 后面会介绍
        },
    ]
}
  1. Плагин webpack-parallel-uglify-plugin (оптимизирует процесс сжатия js)

webpack-parallel-uglify-plugin может разбивать задачи на несколько подпроцессов для одновременного выполнения.После обработки подпроцессов результаты отправляются в основной процесс, чтобы добиться параллельной компиляции и значительно повысить скорость сжатия js.

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');

// ... optimization: { minimizer: [ new ParallelUglifyPlugin({ // 多进程压缩 cacheDir: '.cache/', uglifyJS: { output: { comments: false, beautify: false }, compress: { warnings: false, drop_console: true, collapse_vars: true, reduce_vars: true } } }), ] }

  1. HappyPack

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

const HappyPack = require('happypack');
module.exports = {
	entry: './src/index.js',
	output: {
		path: path.join(__dirname, './dist'),
		filename: 'main.js',
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                use: 'happypack/loader?id=babel',
            },
        ]
    },
    plugins: [
        new HappyPack({
            id: 'babel',  //id值,与loader配置项对应
            threads: 4,  //配置多少个子进程
            loaders: ['babel-loader']  //用什么loader处理
        }),
    ]
}
  1. динамическое связывание DLL

Сторонняя библиотека не обновляется часто, и есть надежда, что она будет упакована отдельно при упаковке для повышения скорости упаковки. Для упаковки dll необходимо создать новый файл конфигурации вебпака (webpack.dll.config.js) При упаковке dll вебпак делает индекс и записывает его в файл манифеста. Затем вам нужно только прочитать файл манифеста при упаковке файла проекта.

const webpack = require("webpack");
const path = require('path');
const CleanWebpackPlugin = require("clean-webpack-plugin");
const dllPath = path.resolve(__dirname, "../src/assets/dll"); // dll文件存放的目录

module.exports = { entry: { // 把 vue 相关模块的放到一个单独的动态链接库 vue: ["babel-polyfill", "fastclick", "vue", "vue-router", "vuex", "axios", "element-ui"] }, output: { filename: "[name]-[hash].dll.js", // 生成vue.dll.js path: dllPath, library: "dll[name]" }, plugins: [ new CleanWebpackPlugin(["*.js"], { // 清除之前的dll文件 root: dllPath, }), new webpack.DllPlugin({ name: "dll[name]", // manifest.json 描述动态链接库包含了哪些内容 path: path.join(__dirname, "./", "[name].dll.manifest.json") }), ], };

Далее вам нужно добавить команду dll в package.json.

"scripts": {
    "dll": "webpack --mode production --config build/webpack.dll.config.js"
}

После запуска npm run dll будут сгенерированы файлы описания ресурсов ./src/assets/dll/vue.dll-[hash].js public js и ./build/vue.dll.manifest.json. dll работа по подготовке завершена, на нее можно ссылаться в webpack.

externals: {
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'vuex': 'vuex',
    'elemenct-ui': 'ELEMENT',
    'axios': 'axios',
    'fastclick': 'FastClick'
},
plugins: [
    ...(config.common.needDll ? [
        new webpack.DllReferencePlugin({
            manifest: require("./vue.dll.manifest.json")
        })
    ] : [])
]

7 Как webpack оптимизирует производительность интерфейса

  1. Загрузка сторонних библиотек по запросу, ленивая загрузка маршрутов
//第三方ui库element,vant等库都提供来按需加载的方式,避免全部引入,加大项目体积
import { Button, Select } from 'element-ui';

//路由懒加载 const showImage = () => import('@/components/common/showImage');

  1. разделение кода
  • Извлечь сторонние библиотеки"vendor"
module.exports = {
    entry: {
        main: './src/index.js',
        vendor: ['react', 'react-dom'],
    },
}
  • Разделение библиотеки зависимостей"splitChunks"
optimization: {
  splitChunks: {
     chunks: "async", // 必须三选一: "initial" | "all"(推荐) | "async" (默认就是async)
     minSize: 30000, // 最小尺寸,30000
     minChunks: 1, // 最小 chunk ,默认1
     maxAsyncRequests: 5, // 最大异步请求数, 默认5
     maxInitialRequests : 3, // 最大初始化请求书,默认3
     automaticNameDelimiter: '~',// 打包分隔符
     name: function(){}, // 打包后的名称,此选项可接收 function
     cacheGroups:{ // 这里开始设置缓存的 chunks
         priority: 0, // 缓存组优先级
         vendor: { // key 为entry中定义的 入口名称
             chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是async)
             test: /react|lodash/, // 正则规则验证,如果符合就提取 chunk
             name: "vendor", // 要缓存的 分隔出来的 chunk 名称
             minSize: 30000,
             minChunks: 1,
             enforce: true,
             maxAsyncRequests: 5, // 最大异步请求数, 默认1
             maxInitialRequests : 3, // 最大初始化请求书,默认1
             reuseExistingChunk: true // 可设置是否重用该chunk
         }
     }
  }
 },
  1. Удалить лишний код

"Tree-Shaking"

Группа передовых рыболовных технологий Brother Shark

Приветствую всех на технических биржахСвязь