web/webpack

Webpack介绍

Copyright @ 后盾网 houdunwang.com

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(less,ES6等),并将其打包为合适的格式以供浏览器使用。

Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。

安装命令

使用npm 或 cnpm 安装webpack及相关的软件包

cnpm i --save-dev webpack html-webpack-plugin babel-cli babel-loader babel-core babel-preset-env style-loader css-loader less-loader less postcss-loader precss autoprefixer less sass-loader node-sass html-loader file-loader url-loader  uglifyjs-webpack-plugin webpack-dev-server

打包实例

配置文件

webpack.config.js是webpack 使用的配置文件

module.exports = {
    entry: {
        //入口文件
        main: './app.js'
    },
    output: {
        //保存目录 __dirname指根目录
        path: __dirname + '/dist',
        //打包后的文件
        filename: 'bundle.js',
    }
}

注意这是一个基本的配置文件,后面我们会增强这个文件

目录结构
[image:7CCCF966-17D0-4A0B-B5B6-CBAC1FE6B3A7-1189-0000027EA2D13BC0/A205346F-3566-44A9-9FC8-6F8C085E5EF2.png]
clipboard.png

创建index.html模板文件

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="dist/bundle.js"></script>
</head>
<body>
</body>
</html>

创建主入口文件app.js,他的作用就是来引入我们的项目文件。

require('./hd.js');

创建文件hd.js

document.write('后盾人 人人做后盾');

打包

如果webpack不是全局安装的,通过下面命令运行

./node_modules/webpack/bin/webpack.js 

每次打这么多有点不方便,我们可以将常用的执行脚本写到package.json文件中

"scripts": {
    "start": "webpack --config webpack.config.js"
  },

现在可以直接执行 npm run start 来执行webpack命令了
运行webpack

npm run start

执行成功后会创建打包文件 dist/bundle.js

处理器

处理器(loader)Loaders是webpack中最核心的功能了。loader通过调用外部的脚本或工具对各种格式的文件进行处理,比如说将ES6转换为现代浏览器可以识别的JS文件。
可以在一种文件上应用多个loader,比如我们可以对.less文件使用 less-loader css-loader style-loader等等,在配置文件中最后写的最先应用。
Loaders需要单独安装并且需要在webpack.config.js中配置,Loaders的配置选项包括以下几方面:

  1. test: 一个匹配loaders所处理的文件的扩展名的正则表达式(必须)

  2. use: loader的名称(必须)

  3. include/exclude: 必须处理的文件或文件夹与屏蔽不需要处理的文件或文件夹(可选)

  4. options:为loaders提供额外的设置选项(可选)

Less文件处理

下面通过解析less 实例讲解loader的使用。
处理less需要安装三个处理器:style-loader css-loader less-loader autoprefixer,我们在前面的安装章节已经安装了这三个loader。
配置
修改webpack.config.js配置文件

module.exports = {
    entry: {
        //入口文件
        main: './app.js'
    },
    output: {
        //保存目录 __dirname指根目录
        path: __dirname + '/dist',
        //打包后的文件
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /\.less$/,
                use: [
                    //在html页面中创建style样式标签
                    "style-loader",
                    // 转换 CSS 到 CommonJS
                    "css-loader",
                    {
                        //为浏览器
                        loader: "postcss-loader",
                        options: {
                            //postcss-loader的插件
                            plugins: function () {
                                return [
                                    //为不同浏览器添加栏目前缀
                                    require('autoprefixer')
                                ];
                            }
                        }
                    },
                    "less-loader"
                ]
            }
        ]
    }
}

项目中新增less文件hd.less

body {
  h1 {
    background: #f00;
    display: flex;
  }
}

修改index.html添加标签用于测试效果

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="dist/bundle.js"></script>
</head>
<body>
<h1>后盾网</h1>
</body>
</html>

在app.js入口文件中引入less

require('./hd.less');
require('./hd.js');

执行打包命令后我们在浏览器中就可以看到效果,而且生成的css文件也做了兼容性处理会为不同浏览器加上样式前缀。

npm run start

现在我们掌握了使用loader处理less文件,其他类型的文件也是一样的方式。可以通过查看webpack官网获取更多loader的使用。 https://webpack.js.org/loaders/

JS文件处理

我们继续在webpack.config.js的module/rules配置段添加处理js的配置:

JS使用的loader我们已经在前面的安装部分都安装过了

{
    test: /\.js$/,
    //不分析打包exclude指定的目录
    exclude: /(node_modules|bower_components)/,
    //只分析include指定的目录
    include: /(src)/,
    //将es6转为es5语法
    loader: 'babel-loader',
    options: {
        presets: ['env']
    }
}

也可我们可以在js文件中码 ES6的代码了,执行 npm run start 后会转为ES5的代码适用于所有浏览器了。

options 配置是将ES6转为ES5的声明,也可以写在.babelrc文件中独立配置:

{
    presets: ['env']
}

经过上面的配置我们就可以在项目中使用 const let等ES6语法了。

图片处理

我在webpack.config.js的module/rules配置段添加处理图片loader的配置:

{
    //打包图片
    test: /\.(png|jpg|jpeg|gif|svg)$/,
    use: [{
        loader: 'url-loader'
        , options: {
            //图片小于50K时生成base64图片字符串
            limit: 50000,
            //生成文件名规则
            name: 'dist/images/[sha512:hash:base64:7].[ext]'
        }
    }]
}

修改hd.less

body {
  background: url("1.jpg");
  h1 {
    background: #f00;
    display: flex;
  }
}

执行打包命令 npm start 后系统会将大于50Kb的图片添加到 dist/images目录中,小图生成base64字符串。

插件(Plugins)

插件是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。

版权插件

下面我们通过版权声明插件来演示插件的使用方法。

在配置文件的最开始调用webpack模块

const webpack = require('webpack');

添加配置项 plugins 与module同级

plugins: [
    new webpack.BannerPlugin("copyright@houdunwang.com")
]

执行编译命令后我们会在最终生成的编译文件头部看到版本声明内容。

模板编译

html-webpack-plugin这个插件的作用是根据模板生成最终的HTML5文件,这个文件中自动引用项目使用的JS/CSS等文件,系统会自动插件编译好的JS入口文件。
插件模块 html-webpack-plugin 已经在前面章节安装过了。

在配置文件最开始引入插件

const htmlWebpackPlugin = require('html-webpack-plugin');

在webpack.config.js 的plugins配置段添加:

new htmlWebpackPlugin({
    //静态模板文件
    template: './app.html',
    //生成的文件名,不加路径时生成到output.path设置的目录中
    filename: 'index.html',
    //js文件插入到html中的位置
    inject: 'body',
    //html页面title标签值
    title: '后盾人 - 这是标题部分',
    //使用的入口文件
    chunks: ['main'],
    minify: {
        //删除注释内容
        removeComments: true,
        //删除html中的空格、换行符
        // collapseWhitespace: true,
    }
})

创建模板文件app.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <h1>后盾人 houdunren.com</h1>
</body>
</html>

执行编译命令后系统会将 app.html做为模板生成新的项目文件 dist/index.html

JS压缩插件
uglifyjs-webpack-plugin用于对生成的JS文件进行压缩,在生产环境下压缩过后的文件显然会更节省我们的带宽与提高响应速度。
插件模块 uglifyjs-webpack-plugin 已经在前面章节安装过了。

在配置文件最开始引入插件

const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

在webpack.config.js 的plugins配置段添加:

new UglifyJSPlugin({
    compress: {
        warnings: false
    },
    mangle: {
        except: ['$super', '$', 'exports', 'require']
    }
})

执行 npm start 命令后我们就生成了压缩的JS文件了。

自动刷新

上面的开发中我们要执行以下几步才可以看到效果。

  1. 修改代码

  2. npm start

  3. 手动刷新浏览器
    现在我们可以通过一个插件节省步骤,实现修改完代码后自动刷新浏览器看到效果,如果在开发中我们有2台显示器体验会更好。

修改webpack.config.js配置文件,与output配置同级

devServer: {
    contentBase: path.join(__dirname, "dist"),
    compress: true,
    port: 9000
}

修改package.json添加npm 执行脚本

"scripts": {
    "start": "webpack --config webpack.config.js",
    "dev": "webpack-dev-server"
}

执行npm run dev命令后,在浏览器访问 localhost:9000就可看到效果,现在我们在修改代码后浏览器会自动刷新出结果。

附录

package.json

{
  "name": "houdunren",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "start": "webpack --config webpack.config.js",
    "dev": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^6.7.6",
    "babel-cli": "^6.23.0",
    "babel-core": "^6.23.1",
    "babel-loader": "^6.4.0",
    "babel-preset-env": "^1.2.1",
    "css-loader": "^0.27.1",
    "file-loader": "^0.10.1",
    "html-loader": "^0.4.5",
    "html-webpack-plugin": "^2.28.0",
    "less": "^2.7.2",
    "less-loader": "^3.0.0",
    "node-sass": "^4.5.0",
    "postcss-loader": "^1.3.3",
    "precss": "^1.4.0",
    "sass-loader": "^6.0.3",
    "style-loader": "^0.13.2",
    "uglifyjs-webpack-plugin": "^0.3.0",
    "url-loader": "^0.5.8",
    "webpack": "^2.2.1",
    "webpack-dev-server": "^2.4.1"
  }
}

webpack.config.js

const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
    entry: {
        //入口文件
        main: './app.js'
    },
    output: {
        //保存目录 __dirname指根目录
        path: __dirname + '/dist',
        //打包后的文件
        filename: 'bundle.js',
    },
    devServer: {
        contentBase: "dist",
        compress: true,
        port: 9000
    },
    module: {
        rules: [
            {
                //打包图片
                test: /\.(png|jpg|jpeg|gif|svg)$/,
                use: [{
                    loader: 'url-loader'
                    , options: {
                        limit: 50000,
                        //生成文件名规则
                        name: 'dist/images/[sha512:hash:base64:7].[ext]'

                    }
                }]
            },
            {
                test: /\.less$/,
                use: [
                    //在html页面中创建style样式标签
                    "style-loader",
                    // 转换 CSS 到 CommonJS
                    "css-loader",
                    {
                        //为浏览器
                        loader: "postcss-loader",
                        options: {
                            //postcss-loader的插件
                            plugins: function () {
                                return [
                                    //为不同浏览器添加栏目前缀
                                    require('autoprefixer')
                                ];
                            }
                        }
                    },
                    "less-loader"
                ]
            },
            {
                test: /\.js$/,
                //不分析打包exclude指定的目录
                exclude: /(node_modules|bower_components)/,
                //只分析include指定的目录
                include: /(src)/,
                //将es6转为es5语法
                loader: 'babel-loader'
            }
        ]
    }
    ,
    plugins: [
        new webpack.BannerPlugin("后盾网出品"),
        new htmlWebpackPlugin({
            //静态模板文件
            template: './index.html',
            //生成的文件名,不加路径时会生成到 output.path 属性设置的目录中
            filename: 'index.html',
            //js文件插入到html中的位置
            inject: 'body',
            //html页面title标签值
            title: '后盾人 - 这是标题部分',
            //使用的入口文件
            chunks: ['main'],
            minify: {
                //删除注释内容
                removeComments: true,
                //删除html中的空格、换行符
                // collapseWhitespace: true,
            }
        }),
        new UglifyJSPlugin({
            compress: {
                warnings: false
            },
            mangle: {
                except: ['$super', '$', 'exports', 'require']
            }
        })
    ]
}

后盾网向军
26 声望6 粉丝

HDPHP&HDCMS作者


下一篇 »
ajax跨域访问