Опыт веб-пакета

JavaScript HTML CSS Webpack

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

    project
        - css
            - bootstrap.min.css
            - jb.css
        - fonts
            - 一些bootstrap的字体
        - images
            - 一些项目用到的图片
        - js
            - bootstrap.min.js
            - jquery.min.js
            - jb.js
        - index.html
        - favicon.ico

Предыстория проекта

Это официальный сайт компании, чтобы сделать. Поскольку проект относительно прост, требуется одна страница, без перехода между страницами, поэтому имеется только один файл .html. В проекте используется более обычная разработка bootstrap + jquery, о которой и говорить нечего. Учитывая управляемость CDN, все ресурсы начальной загрузки загружаются локально для справки. В начале проекта используются обычные референсы js и css (css размещается спереди, js размещается сзади).После завершения разработки, если вы обнаружите, что есть лишнее время, вам следует рассмотреть возможность использования webpack обработать его, чтобы закрепить и узнать, что использует webpack.

работа по инициализации

1. Инициализировать

    npm init

先初始化一个 package.json 文件来管理我们 webpack 所依赖的文件包。一路无脑回车即可。

2. Установите веб-пакет

想要用 webpack ,那么你首先肯定要安装 webpack 才可以啊。用以下命令:

    npm install webpack --save

3. webpack.config.js

在根目录下新建一个 webpack.config.js 文件,用来对 webpack 进行配置。
当有这个文件后,我们系可以在命令行中用以下命令来启动配置好的 webpack 了。

    webpack --config webpack.config.js

4. Измените команду упаковки веб-пакета.

以上虽然也可以启动配置好的 webpack。但是每次要输这么一串命令好像有点太长了(懒啊)。所以在 package.json 中修改这样一项:

    "script": {

      + "start": "webpack --config webpack.config.js",

        "test": "echo \"Error: no test specified\" && exit 1"
    }

Таким образом, мы можем сэкономить еще несколько нажатий клавиш в командной строке. Непосредственное использование следующей команды эквивалентно приведенной выше команде:

    npm start

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

webpack.config.js

1. Откуда взялся входной файл?

Что такое входной файл

webpack создает граф зависимостей всех зависимостей приложения. Начальная точка графика называется точкой входа. Точка входа сообщает webpack, с чего начать, и определяет, что нужно упаковать, на основе графа зависимостей. Точку входа приложения можно рассматривать как корневой контекст (контекстный корень) или первый файл запуска приложения.

В отличие от других спа-приложений, такое обычное приложение, все его зависимости исходят из файла index.html. Если есть входной файл, это должен быть сам index.html. но вебпак
По сути, файл .js используется в качестве файла ввода, а файл .html используется в качестве файла ввода... (я его все равно не видел). Если есть какая-либо причина здесь, пожалуйста, обратитесь кэта статья. (правда я тоже не знаю)

Итак, несмотря ни на что, нам нужен входной файл.

Итак, несмотря ни на что, конфигурация веб-пакета, которую мы часто видим, выглядит так:

    module.exports = {
        entry: './index.js'
    }

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

index.js

Вы знаете, для нашего исходного проекта нам вообще не нужен был такой файл index.js (мы могли бы жить без него лучше). Но нам пришлось создать такой файл снова. Так вот вопрос, какой контент нужно поместить в созданный таким образом файл? Мы не должны были сохранять его, создавая такой пустой файл.

Размышляя над этой проблемой, можно сначала взглянуть на ту самую классическую картинку официального вебпака (мне лень, поэтому картинку ставить не буду, каждый может найти в интернете). webpack портит .js .css .png .jpg .sass слева. . . И так далее, все файлы упакованы в статические ресурсы. Другими словами, webpack упаковывает все ресурсы, кроме html, поэтому можем ли мы позволить webpack упаковать их для нас, если мы помещаем все эти ресурсы в файл входа?

Но ждать. С прочим проблем нет, какой css, какой js, легко сказать, потому что используется столько-то, а как же картинки и шрифты? Я использовал так много изображений в проекте, что мне нужно снова записать их все в index.js! МОЙ БОГ! Это фатально! Так может я поленюсь и просто напишу css и js, а на остальное мне наплевать? Тогда приходите сюда первым. Измените наш файл index.js, добавив следующее.

    require('./css/bootstrap.min.css')
    require('./css/jubang.css')
    require('./js/jquery.min.js')
    require('./js/bootstrap.min.js')
    require('./js/jb.js')

Давайте использовать это как наш входной файл

2. Настройте файл экспорта

Файл экспорта хорошо сконфигурирован и упакован в каталог dist в корневом каталоге. Хм~ это очень распространено!

    var path = require('path');
    module.exports = {
        entry: './index.js',
        output: {
            filename: 'bundle.js',
            path: path.resolve(__dirname, 'dist')
        }
    }

3. Настроить загрузчик

Я не знаю, как это настроить, давайте сначала посмотримэта статьяБар.

Итак, здесь наш webpack.config.js выглядит так:

    var path = require('path');

    module.exports = {
        entry: './index.js',
        output: {
            filename: 'bundle.js',
            path: path.resolve(__dirname, 'dist')
        },
        module: {
            rules: [{
                test: /\.css$/,
                use: [
                    'style.loader',
                    'css-loader'
                ]
            }, {
                test: /\.(png|jpg|svg|git)$/,
                use: [
                    'file-loader'
                ]
            }, {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            }]
        }
    }

Здесь мы используем три загрузчика, которые нужно установить в первую очередь

    npm install css-loader style-loader file-loader --save

Функции этих трех загрузчиков следует поискать в сети самостоятельно.

4. Первая упаковка

配置到这里,我们可以先来打包一下,有问题再改嘛!

命令行切换到项目目录下,执行以下命令:

    npm start


打包结束后,项目的目录结构

    project
        - css
        - dist
        - fonts
        - images
        - js
        - node-modules
        - favicon.ico
        - index.html
        - index.js
        - package.json
        - webpack.config.js

我们可以看到,项目根目录下面多出来一个 dist 的目录。没错,这个就是我们 webpack 打包后文件生成的目录,至于为什么会是 dist 目录,那是因为你在 webpack.config.js 的 output 中设置的 path。


现在我们来查看下 webpack 打包出了什么东西

        - dist
            - xxxx.jpg
            - xxxx.woff2
            - xxxx.jpg
            - xxxx.svg
            - bundle.js
            - xxxx.ttf
            - xxxx.eot
            - xxxx.woff

Примечание: xxxx представляет собой комбинацию цифр и букв, которая написана для удобства.

打包文件中生成了一个 .js 文件,两个 .jpg 文件,四个字体文件(.woff2、.ttf、.eot、.woff),和一个 .svg 文件

我们来看下这是个类型的文件都来自哪里吧

1. bundle.js

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

2. .jpg

Откуда взялись два файла .jpg? Посмотрев на две картинки, на самом деле, мы узнаем, что эти две картинки написаны нами самими.jb.cssиспользуется в качествеbackground-imageпредставил. Мы сказали, что webpack будет использовать текст записи в качестве отправной точки и упаковать его в соответствии с графом зависимостей. Другими словами, мы зависим от входного файлаjb.css,а такжеjb.cssЭто зависит от двух изображений .jpg, поэтому webpack упаковал эти два изображения вместе в соответствии с анализом зависимостей.

3. Файл шрифта + svg

Источник четырех файлов шрифтов требует от нас определенного понимания начальной загрузки. Если вы знакомы с бутстрапом, то знаете, что в зависимостях бутстрапа он опирается на эти шрифты, а это значит, что эти файлы шрифтов упакованы из файла bootstrap.min.css. На самом деле, когда я работал над этим проектом, когда я получил исходный код начальной загрузки локально, я обнаружил, что есть папка шрифтов, которая является папкой шрифтов в корневом каталоге нашего проекта, Там будет четыре файла, заканчивающиеся с тем же файлом Файлы шрифтов и файл svg, заканчивающийся на .svg. И эти пять файлов не те пять файлов, которые у нас есть.

Если вы все еще не в своей тарелке, мы можем сделать еще одну проверку. Измените файл webpack.config.js.

    {
        test: /\.(png|jpg|svg|git)$/,
        use: [
        -    'file-loader'
        +    'file-loader?name=[hash:8].[name].[ext]'
        ]
    }, {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
        -    'file-loader'
        +    'file-loader?name=[hash:8].[name].[ext]'
        ]
    }

Мы помещаем файлы изображений и шрифтов в формат «8-битное хэш-значение-исходное имя файла-суффикс имени» после обработки файловым загрузчиком, затем мы можем сравнить источники этих файлов.
После переупаковки (сначала нужно удалить исходную папку dist) мы видим, что наше предположение было верным!

4. Унаследованные проблемы

Несмотря на то, что наша первая упаковка прошла успешно, осталось еще несколько нерешенных проблем: Во-первых, мои js, css, шрифты, картинки и другие ресурсы были упакованы в каталог dist, но, поскольку наш проект самый важный Что насчет файла index.html ? Без этого файла какой смысл в том, что мы запаковывали! . Во-вторых, у меня в папке с изображениями так много картинок.Почему после упаковки с вебпаком у вас только две картинки?А остальные?

Тогда давайте решать это срочно.

5. html-webpack-plugin

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

    npm install html-webpack-plugin --save

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

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

在 module 后面加

    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html'
        })
    ]

Мы добавили плагин в файл конфигурации и передали конструктору HtmlWebpackPlugin параметр объекта, в котором мы указали поле шаблона, которое представляет собой источник html-файла, который мы хотим запаковать. Затем мы переупаковываем и смотрим в наш каталог, чтобы увидеть, что в каталоге dist есть дополнительный index.html. Поскольку этот проект сам по себе является простым проектом, который не зависит от какой-либо среды, если он нормальный, мы можем напрямую открыть страницу index.html и нормально отобразить ее в браузере. Хотя я не знаю, что произойдет, давайте откроем его и попробуем.

Когда мы открыли index.html и отобразили его в браузере, мы обнаружили, что в браузере отсутствуют многие изображения. Взглянув на код нашего проекта, мы обнаружили, что, кроме фонового изображения в jb.css, не отображалось ни одно из изображений, определенных в теге img.

Итак, несмотря на то, что с этой конфигурацией файла все еще есть некоторые проблемы, давайте сначала решим проблему с img в html, что является второй проблемой, о которой мы упоминали выше.

6. html-withimg-loader

Для решения второй проблемы (то есть проблемы с img в html) нам нужно использовать html-whithimg-loader, вы можете проверить, как использовать этотздесь.

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

    {
        test: /\.(html|htm)$/,
        use: [
            'html-withimg-loader'
        ]
    }

Это правило конфигурации указывает, что все html-файлы, которые должны быть обработаны, сначала будут обработаны загрузчиком html-withimg-loader. Это достаточно просто, чтобы решить нашу вторую проблему? Попробуйте, события — единственный тест на истину.

Изменить каталог ресурсов

Переупакуйте, а потом проверьте каталог dist. Это не имеет значения. Я обнаружил, что в каталоге dist много файлов с картинками, которые плотные и беспорядочные. Могут ли это быть картинки в нашем html? Зажмите свое обсессивно-компульсивное расстройство, сначала найдите index.html (то, что нас больше всего беспокоит, это он), откройте его, а затем просмотрите эффект в браузере. Узнал, что наши картинки уже есть, и стили почти правильные. Но как такой беспорядочный каталог dist может быть результатом, которого мы, обсессивно-компульсивные пациенты, хотим! Мы хотим поместить картинки в папку с картинками, шрифты в папку со шрифтами и позволить ему оставаться снаружи для нескольких других. Давайте сделаем это, давайте подправим наш файл конфигурации

        {
            test: /\.(png|jpg|svg|git)$/,
            use: [
            -    'file-loader?name=[hash:8].[name].[ext]'
            +    'file-loader?name=images/[hash:8].[name].[ext]'
            ]
        }, 
        {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
            -    'file-loader?name=[hash:8].[name].[ext]'
            +    'file-loader?name=fonts/[hash:8].[name].[ext]'
            ]
        } 

автоматически удалить дист.

Есть еще одна проблема, которую я терпел уже давно.Перед каждой упаковкой нам нужно вручную удалить директорию dist, оставшуюся от последней упаковки.Это раздражает.Хотя это просто удаление,но тоже надоедает делать много чего! Мы задались вопросом, можем ли мы позволить веб-пакету сделать это за нас автоматически, поэтому нам не нужно было удалять его вручную. К счастью, webpack достаточно умен, чтобы всегда решать всевозможные необоснованные проблемы, которые вы поднимаете. Но сначала нам нужно установить плагин:

    npm install clean-webpack-plugin --save

Затем добавьте ссылку на этот плагин в файл конфигурации.

    var HtmlWebpackPlugin = require('html-webpack-plugin');
    +   var CleanWebpackPlugin = require('clean-webpack-plugin');

Добавить использование этого плагина в плагинах

    new CleanWebpackPlugin(['dist'])

Таким образом, нам не нужно удалять папку dist вручную.

Попробуйте еще раз!

После упаковки мы сразу же почувствовали себя значительно обновленными, когда посмотрели на каталог dist!

    - dist
        - fonts
            - 一些字体文件
        - images
            - 一些图片文件

        - bundle.js
        - index.html

Изменить index.html

Снова просмотрите упакованный проект в браузере и проверьте консоль, чтобы обнаружить, что консоль сообщила о множестве ошибок. Некоторые из них являются ошибками, связанными с некоторыми файлами css, js. Потому что мы упаковали все необходимые css и js в bundle.js. И наш исходный проект импортируется в html-файлы один за другим через статическую ссылку на ресурс. Поэтому, когда мы успешно упаковываем webpack, нам не нужно ссылаться на эти ресурсы, нам нужно только сослаться на bundle.js (наш упакованный файл).К счастью, упакованный файл webpack автоматически цитирует нас. Так что просто удалите эти css и js в index.html в исходном проекте. Тогда после перепаковки не будет ляпов, что эти ресурсы не могут быть найдены.

Однако с нашим файлом .ico есть небольшая проблема. Это файл значка для нашего веб-сайта. Как исправить его ошибку цитирования? Мы можем сначала решить эту проблему при генерации html. Изменить файл конфигурации

    new HtmlWebpackPlugin({
        template: './index.html',
    +    favicon: path.resolve(__dirname, './favicon.ico')
    })

В этом случае наш файл иконки тоже будет там.

7. О jquery

Хотя некоторые неудобные ошибки цитирования были устранены, консоль оставила проблему, доставившую нам много головной боли: проблема цитирования jQuery:

    Uncaught Error: Bootstrap's JavaScript requires jQuery

Здесь нам нужно использовать expose-loader, о нем вы можете узнатьздесь, не много ерунды:

    npm install expose-loader --save

Добавить еще один загрузчик в правила модуля

    {
        test: require.resolve('./js/jquery.min.js'), // 引入 jquery
        use: [{
            loader: 'expose-loader',
            options: '$'
        }, {
            loader: 'expose-loader',
            options: 'jQuery'
        }]
    }

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

8. Извлечь css

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

Причину легко понять, потому что мы упаковали и css, и js в один и тот же bundle.js. Однако этот bundle.js загружается в конце страницы. То есть наши стили загружаются внизу страницы. Это совершенно не то, что мы ожидали. Мы хотим, чтобы стили загружались в голову, а js-скрипт загружался внизу страницы. Поэтому мы не можем упаковать css и js вместе в bundle.js.

extract-text-webpack-plugin

смотрите подробностиздесь

    npm install extract-text-webpack-plugin --save

увеличение требует

    var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');

Изменить правила css

    {
        test: /\.css$/,
        use: ExtractTextWebpackPlugin.extract[{
            fallback: 'style-loader',
            use: 'css-loader'
        }]
    }

добавить плагин

    new ExtractTextWebpackPlugin('style.css')

Упаковка, и тогда мы обнаружим, что в dist есть еще один style.css, а затем еще ссылки на этот css в заголовке index.html

9. Другие

1. Сжать js

добавить плагин

    new webpack.optimize.UglifyJsPlugin({
        compress: {
            warnings: false
        }
    })

2. Сжать html

new HtmlWebpackPlugin({
    template: './index.html',
    favicon: path.resolve(__dirname, './favicon.ico'),
    minify: {
        removeAttributeQuotes: true,
        removeComments: true,
        removeEmptyAttribute: true,
        collapseWhitespace: true
    }
}),

3. Оптимизируйте изображения

    {
        test: /\.(jpg|png|gif|svg)$/,
        - use: 'file-loader?name=images/[hash:8].[name].[ext]'
        + use: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
    }

Суммировать

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

Справочная документация

webpack (v3.5.5) китайская документация