Webpackプラグインの詳しい説明

php中世界最好的语言
リリース: 2018-03-19 17:12:21
オリジナル
2695 人が閲覧しました

今回は、webpack プラグインについて詳しく説明します。webpack プラグインを使用する際の 注意事項 は何ですか?実際の事例を見てみましょう。

1. HTML を自動的に構築し、スペースを圧縮し、参照される js にバージョン番号または乱数を追加します: html-webpack-plugin

2. CSS を処理します: css-loader と style-loader
3. LESS を処理します。 less
4. CSS コードを CSS ファイルに抽出します: extract-text-webpack-plugin
5. 開発環境でのサーバー構築: webpack-dev-server
6. ES6 コードを解析します: babel-core babel-preset-env babel-loader
7. ES6 の新しいオブジェクト関数を分析する: babel-polyfill
8. React の jsx 構文を分析する: babel-preset-react
9. 相対パスを絶対パスに変換する: nodejs のパス モジュール
10.ファイル: [chunkhash]、[hash]
11. 出力フォルダーの前に出力ファイルをクリアします: clean-webpack-plugin
12. モジュールのホット置換: NamedModulesPlugin および HotModuleReplacementPlugin
13. クロス プラットフォームは環境変数を使用します。 :cross-env
15.画像パスの処理:file-loader と html-loader
16.画像圧縮:image-webpack-loader
17.ソースファイルコードの配置:source-map
18.開発環境のファイル

1. HTML を自動的に構築し、スペースを圧縮し、参照される js にバージョン番号または乱数を追加します: html-webpack-plugin

解決策: プラグイン html-webpack-plugin

webpack を使用します。 .config.jsは次のとおりです:

module.exports = {
  entry: './src/app.js',
  output: {
    path: dirname + '/dist',
    filename: 'app.bundle.js'
  },
  plugins: [new HtmlWebpackPlugin({
    template: './src/模板文件.html',
    filename: '构建的.html',
    minify: {
      collapseWhitespace: true,
    },
    hash: true,
  })]
};
ログイン後にコピー

出力HTMLは出力ディレクトリを知る必要があるため、パスに注意してください

2. CSSの処理: css-loaderとstyle-loader

loaderを使用して事前準備しますハンドル変換モジュールのソースコード。

解決策: css-loader、style-loader を使用します

プロジェクト構造を確認してください:


この時点で webpack コマンドを実行すると、エラーがスローされます: Webpackプラグインの詳しい説明


次に css-loader と style-loader をインストールしますWebpackプラグインの詳しい説明

npm install --save-dev css-loader style-loader
ログイン後にコピー
webpack.config.js を次のように変更します:


rules 配列は、ローダーがリソースの照合と変換に使用するルールの配列です。 Webpackプラグインの詳しい説明test は、変換されるファイルに一致する

正規表現

を表し、図は、css で終わるすべてのファイルに一致することを示しています。
use 配列は、これらの一致したファイルを処理するためにどのローダーが使用されるかを表します。 この時点で webpack を再度実行すると、パッケージ化されたファイル Bundle.js に CSS コードが含まれます。
css-loader は、CSS のロードと CSS の JS へのパッケージ化を担当します。

スタイルローダーは生成を担当します。js の実行中に、css コードが style タグを通じて dom に挿入されます。


3. LESS への対処:less-loade とless

解決策:less-loader を使用します

ただし、less-loader を使用すると、LESS コードが CSS コードに変換されるだけです。ファイルを js にパッケージ化したい場合は、前述の css-loader と style-loader を使用する必要があります。

プロジェクトの構造を見てください:


次に、app.js のコードは次のとおりです: Webpackプラグインの詳しい説明

import styles from './app.less';
console.info('我是一个js文件123')
ログイン後にコピー
この状況を解決するには、まずless-loaderをインストールする必要があります。less-loaderはlessに基づいているため、インストールする必要があるものも少なくなります。

npm i --save-dev less less-loader
ログイン後にコピー
webpack.config.js を次のように変更します:

module: {
  rules: [
    {
      test: /\.less$/,
      use: [ 'style-loader', 'css-loader', 'less-loader' ]
    }
  ]
}
ログイン後にコピー
4. CSS コードを CSS ファイルに抽出します: extract-text-webpack-plugin

多くの場合、私たちが望む効果は、複数の LESS または CSS After 処理を結合しないことです。 、jsにパッケージ化していますが、cssファイルにパッケージ化したいと考えています。

プラグイン extract-text-webpack-plugin が利用できるようになりました。

まずインストール

npm i --save-dev extract-text-webpack-plugin
ログイン後にコピー

次に webpack.config.js を次のように変更します:

与原配置对比可以发现,比html-webpack-plugin这个插件多做了一步,就是在匹配和转换规则里面的use中使用了ExtractTextPlugin.extract。
注意这里的fallback表示,在提取文件失败后,将继续使用style-loader去打包到js中。
此时运行webpack
可以发现输出目录build下生成了一个style.css文件,也就是我们在webpack.config.js中期望生成的文件,并且在生成的demo.html中被引用了。

5.开发环境下的服务器搭建:webpack-dev-server

webpack-dev-server可以在本地搭建一个简单的开发环境用的服务器,自动打开浏览器,而且还可以达到webpack -watch的效果。
首先安装一下:

npm i -g  webpack-dev-server
npm i --save-dev webpack-dev-server
ログイン後にコピー

这里不需要改动webpack.config.js,直接运行命令

webpack-dev-server
ログイン後にコピー

查看Webpackプラグインの詳しい説明:
Webpackプラグインの詳しい説明

显示项目运行在http://localhost:8080/
webpack的输出目录的路径在/下面
并且这个服务器会自动识别输出目录下名为index的HTML文件,而我们之前输出的文件名为demo.html。
所以还需要将之前html-webpack-plugin中配置的filename改为index.html,或者直接用http://localhost:8080/demo.html也行。
当我们修改了源代码后,打开的网页还会自动更新。

为了更灵活的应用开发环境的服务器,也可以在webpack.config.js中加入如下代码:
Webpackプラグインの詳しい説明

devServer配置 功能
port 修改端口为8787,而不是默认的8080。
open 为true表示会自动打开浏览器,而不是需要我们再手动打开浏览器并在里面输入http://localhost:8080。
compress 对本地server返回的文件提供gzip压缩
index 指定网站首页映射的文件,默认为index.html

6.解析ES6代码:babel-core babel-preset-env babel-loader

这里说是ES6,实际上可以认为是ECMAScript的高版本代码,只是代指而已。
babel的作用是将浏览器还未支持的这些高版本js代码转换成可以被指定浏览器支持的js代码。

这里列出可以转换的大致语法:
Webpackプラグインの詳しい説明

那么首先就需要安装babel

npm install babel-core babel-preset-env --save-dev
ログイン後にコピー

然后,为了和webpack结合起来,要用到babel-loader

npm install babel-loader --save-dev
ログイン後にコピー

然后在webpack.config.js的rules数组中增加以下代码:

{
  test: /\.js$/,
  exclude: /(node_modules)/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['env']
    }
  }
}
ログイン後にコピー

这行代码的意思是用babel-loader解析除了node_modules文件下的所有js文件。
而babel-loader就是用babel去解析js代码。
options的内容类似于.babelrc文件的配置,有了这个就不需要.babelrc文件了。
presets表示预处理器,现在的babel不像以前需要很多预处理器了,只需要env这一个就够了。

修改之前的app.js中的代码为:

console.info('我是一个js文件123')
const doSomething=() => {
  console.info('do do do')
}
ログイン後にコピー

使用webpack命令后,可以看到我们最后的打包js文件中代码变成了这样:
Webpackプラグインの詳しい説明

7.解析ES6新增的对象函数:babel-polyfill

以下为这些新增函数:
Webpackプラグインの詳しい説明

安装:

npm install --save-dev babel-polyfill
ログイン後にコピー

为了确保babel-polyfill被最先加载和解析,所以一般都是讲babel-polyfill在最开始的脚本中引入。
而在webpack中,就是在放到entry中,所以需要修改webpack.config.js中的配置为:

Webpackプラグインの詳しい説明

8.解析react的jsx语法:babel-preset-react

安装

npm install --save-dev babel-preset-react
ログイン後にコピー

配置:
Webpackプラグインの詳しい説明

这里是匹配所有以js或者jsx结尾的文件,并用 babel-preset-env和babel-preset-react进行解析

9.转换相对路径到绝度路径:nodejs的path模块

这里首先介绍一下nodejs的path模块的一个功能:resolve。
将相对路径转换为绝对路径。
在最开始引用path模块

var path = require('path');
ログイン後にコピー

然后可以在输出设置那里修改代码为:

  output: {
    path: path.resolve(dirname, 'build'),
    filename: 'bundle.js'
  },
ログイン後にコピー

和我们原来的代码没有任何区别。

10.给文件加上hash值:[chunkhash],[hash]

hash和chunkhash有区别,hash的话输出的文件用的都是同一个hash值,而chunkhash的话是根据模块来计算的,每个输出文件的hash值都不一样。
直接将输出文件改为

output: {
  path: path.resolve(dirname, 'build'),
  filename: 'bundle.[chunkhash].js'
},
ログイン後にコピー

[chunkhash]就代表一串随机的hash值

11.清空输出文件夹之前的输出文件:clean-webpack-plugin

当我们像上面一样不断改变输出文件时,之前的输出文件并没有去掉。
为了解决这个问题就需要clean-webpack-plugin。
首先安装

npm i clean-webpack-plugin --save-dev
ログイン後にコピー

然后引用插件,并声明每次生成输出需要清空的文件夹

var CleanWebpackPlugin = require('clean-webpack-plugin');
var pathsToClean = [
  'build',
]
ログイン後にコピー

再在插件配置中加入:

new CleanWebpackPlugin(pathsToClean)
ログイン後にコピー

12.模块热替换:NamedModulesPlugin和HotModuleReplacementPlugin

之前的webpack-dev-server提供了监听功能,只要代码改变,浏览器就会刷新。
但是模块热替换是不会刷新浏览器,只刷新修改到的那部分模块。
模块热替换无需安装。
首先需要引入模块

var webpack = require('webpack')
ログイン後にコピー

其实插件中加入:

new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
ログイン後にコピー

此时运行webpack可能会报错,我们需要把之前在输出环境中写的[chunkhash]改为[hash]

13.环境变量

可以在脚本中这么写:

"scripts": {
"dev": "webpack-dev-server",
"prod": "set NODE_ENV=production && webpack -p"
},

这样在webpack.config.js中这样修改上面的东西:

Webpackプラグインの詳しい説明

if (isProduction) {
    config.output.filename = 'bundle.[chunkhash].js'
} else {
    config.plugins.push(new webpack.NamedModulesPlugin())
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
}
ログイン後にコピー

这样就可以根据环境的不同来运行不同的配置

14.跨平台使用环境变量: cross-env

上述设置环境变量的脚本中只有在window下才有效,在linux和mac上需要使用

"prod": "NODE_ENV=production webpack -p"
ログイン後にコピー

为了解决这个问题,使得不同平台的人能公用一套代码,我们可以使用cross-env。
首先进行安装:

npm i --save-dev cross-env
ログイン後にコピー

然后命令直接使用类似于mac上的用法即可

"prod": "cross-env NODE_ENV=production webpack -p"
ログイン後にコピー

15.处理图片路径: file-loader和html-loader

file-loader可以用来处理图片和字体文件在css文件中的路径问题,输出的css文件中会引用输出的文件地址。
html-loader可以用来处理html中,比如img元素的图片路径问题。
首先安装

npm i --save-dev file-loader html-loader
ログイン後にコピー

配置:

        {
            test: /\.(gif|png|jpe?g|svg)$/i,
            use: {
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]',
                    outputPath: 'src/images/'
                }
            }
        },
        {
            test: /\.html$/,
            use: [{
                loader: 'html-loader',
                options: {
                    minimize: true
                }
            }],
        }
ログイン後にコピー

16.图片压缩:image-webpack-loader

安装:

npm i --save-dev image-webpack-loader
ログイン後にコピー

配置:

    {
            test: /\.(gif|png|jpe?g|svg)$/i,
            use: [{
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'images/'
                    }
                },
                {
                    loader: 'image-webpack-loader',
                    options: {
                        bypassOnDebug: true,
                    }
                }
            ]
        },
ログイン後にコピー

这里的options中也可以具体配置各个图片类型的压缩质量

17.定位源文件代码:source-map

如果我们用web-dev-server运行我们的输出文件,发现其中有些BUG,然后打开开发者工具取定位文件的时候,只会定位到我们的输出文件。
而这些输出文件是经过处理的,我们只有找到我们的源文件代码,然后进行相应的修改才能解决问题。
于是这里我们需要用到source-map。
很简单,在webpack.config.js中加入如下配置即可:

devtool: 'source-map',
ログイン後にコピー

就这么简单,还不需要安装什么插件。
但是这只对js有效,如果我们的css出现错误了呢,答案就是如下配置:
Webpackプラグインの詳しい説明

18.分离生产环境和开发环境的配置文件

之前我们通过在命令中设置环境变量,并且通过环境变量来判断环境来进行不同的配置。
现在我们用官方推荐的方法来分离生产环境和开发环境的配置文件。
我们将webpack.config.js分为三个文件

  • webpack.common.js

  • webpack.dev.js

  • webpack.prod.js

其中webpack.common.config.js为生产环境和开发环境共有的配置,dev为开发环境独有的配置,prod为生成环境独有的配置。
而想要合成真正的配置文件,还需要一个工具:webpack-merge。

  npm install --save-dev webpack-merge
ログイン後にコピー

以下是我们之前的webpack.config.js代码:

var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var CleanWebpackPlugin = require('clean-webpack-plugin')
var path = require('path')
var webpack = require('webpack')
var pathsToClean = [
    'build',
]
var isProduction = process.env.NODE_ENV === 'production'
var config = {
    entry: ['babel-polyfill', './src/app.js'],
    output: {
        path: path.resolve(dirname, 'build'),
        filename: '[name].[hash].js'
    },
    devtool: 'source-map',
    devServer: {
        port: 8787,
        open: true,
        compress: true,
        index: 'demo.html'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './template/index.html',
            filename: 'demo.html',
            minify: {
                collapseWhitespace: true,
            },
            hash: true
        }),
        new ExtractTextPlugin({ filename: 'style.css', allChunks: false }),
        new CleanWebpackPlugin(pathsToClean)
    ],
    module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader?sourceMap']
                })
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader?sourceMap', 'less-loader?sourceMap']
                })
            },
            {
                test: /\.jsx?$/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['env', 'react']
                    }
                }
            },
            {
                test: /\.(gif|png|jpe?g|svg)$/i,
                use: [{
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'images/'
                        }
                    },
                    {
                        loader: 'image-webpack-loader',
                        options: {
                            bypassOnDebug: true,
                        }
                    }
                ]
            },
            {
                test: /\.html$/,
                use: [{
                    loader: 'html-loader',
                    options: {
                        minimize: true
                    }
                }],
            }
        ]
    }
};
if (isProduction) {
    config.output.filename = '[name].[chunkhash].js'
} else {
    config.plugins.push(new webpack.NamedModulesPlugin())
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
}
module.exports = config
ログイン後にコピー

接下来分为三个文件,webpack.common.js:
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var CleanWebpackPlugin = require('clean-webpack-plugin')
var path = require('path')
var webpack = require('webpack')

var pathsToClean = [
    'build',
]
var isProduction = process.env.NODE_ENV === 'production'
module.exports = {
    entry: ['babel-polyfill', './src/app.js'],
    output: {
        path: path.resolve(dirname, 'build'),
        filename: '[name].[chunkhash].js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './template/index.html',
            filename: 'demo.html',
            minify: {
                collapseWhitespace: true,
            },
            hash: isProduction
        }),
        new ExtractTextPlugin({ filename: '[name].[contenthash].css', allChunks: false }),
        new CleanWebpackPlugin(pathsToClean)
    ],
    module: {
        rules: [{
                test: /\.jsx?$/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['env', 'react']
                    }
                }
            },
            {
                test: /\.(gif|png|jpe?g|svg)$/i,
                use: [{
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'images/'
                        }
                    },
                    {
                        loader: 'image-webpack-loader',
                        options: {
                            bypassOnDebug: true,
                        }
                    }
                ]
            },
            {
                test: /\.html$/,
                use: [{
                    loader: 'html-loader',
                    options: {
                        minimize: true
                    }
                }],
            }
        ]
    }
};
ログイン後にコピー

然后是webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = merge(common, {
    output: {
        filename: '[name].[hash].js'
    },
    devtool: 'source-map',
    devServer: {
        port: 8787,
        open: true,
        compress: true,
        index: 'demo.html'
    },
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ],
    module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader?sourceMap']
                })
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader?sourceMap', 'less-loader?sourceMap']
                })
            }
        ]
    }
});
ログイン後にコピー

最后是webpack.prod.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = merge(common, {
    module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader']
                })
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'less-loader']
                })
            }
        ]
    }
});
ログイン後にコピー

然后修改一下package.json中的脚本即可

  "scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "prod": "cross-env NODE_ENV=production webpack -p --config webpack.prod.js"
},
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

React中有哪些类定义组件

正则表达式怎么在字符串中提取数字

以上がWebpackプラグインの詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート