webpack构建项目

小说:诛仙3破军挂机设置作者:道董更新时间:2018-09-19字数:22775

webpack构建项目


webpack构建项目

源码戳这里
ps:每个案例对应相应的demo,例如“案例1”对应“demo1”

一、webpack基本功能及简单案例

  • 安装webpack
    $ npm i webpack -g

  • 基本功能
    $ webpack -v 查看webpack版本号
    $ webpack 最基本的启动webpack的方法
    $ webpack -w 提供watch方法;实时进行打包更新
    $ webpack -p 对打包后的文件进行压缩
    $ webpack -d 提供source map,方便调式代码
    $ webpack --display-error-details 显示更多报错信息




案例1

  1. 构建项目文件夹

    新建文件夹:
    webpack/src

    新建文件:
    webpack/package.json
    webpack/webpack.config.js
    webpack/src/index.js
    webpack/src/index.less
    webpack/src/index.html

    如下图所示
    1

    webpack/src/index.html 内容如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
    </body>
    <script src="../build/app.js"></script>
    </html>

    webpack/src/index.less 内容如下

    body {
        background: yellow;
    }

    webpack/src/index.js 内容如下

    console.log(123)
  2. 运行 $ npm init

    入下图所示
    2

    然后就看到webpack/package.json文件的内容,如下

    {
        "name": "webpack",
        "version": "1.0.0",
        "description": "",
        "main": "webpack.config.js",
        "scripts": {
            "test": "echo "Error: no test specified" && exit 1"
        },
        "author": "",
        "license": "ISC"
    }
  3. webpack.config.js配置

    webpack/webpack.config.js文件的内容,如下

    var webpack = require("webpack");
    module.exports = {
        entry: "./src/index.js", // 入口文件地址
        output: {
            filename: "./build/app.js" // 输出文件地址和名字
        },
        module: {
            loaders: [
                {
                    test: /.js$/,  // js-loader
                    loader: "babel-loader?presets=es2015"
                },
                {
                    test: /.css$/, // css-loader
                    loader: "style-loader!css-loader"
                },
                {
                    test: /.less/, // less-loader
                    loaders: "style-loader!css-loader!less-loader"
                }
            ],
        }
    }

    分析如下图
    5

    安装依赖
    • 安装webpack依赖
      $ npm i webpack --save-dev
      $ npm i webpack@x.x.x --save-dev(安装指定版本的webpack)

    • 安装css依赖
      $ npm i css-loader --save-dev
      $ npm i style-loader --save-dev

    • 安装less依赖
      $ npm i less --save-dev
      $ npm i less-loader --save-dev

    • 安装es6依赖
      $ npm i babel-loader --save-dev
      $ npm i babel-preset-es2015 --save-dev
      $ npm i babel-core --save-dev

    这个时候再看webpack/package.json文件,就会发现多了一部分内容,如下图所示
    7

  4. 运行 $ webpack

    会发现项目文件夹下多了一个文件 webpack/build/app.js,如下图所示
    3

    打开在浏览器打开webpack/src/index.html,会看到如下图所示
    4

    这样我们已经有了一个简单的案例,在入口文件index.js里引入相关的依赖,然后通过webpack把他们打包好,并生成到build/app.js文件里。在index.html里只需要引入app.js文件,就能够看到背景色和console.log打印的值。

    如下图所示
    6

    webpack/package.json

    {
        "name": "webpack",
        "version": "1.0.0",
        "description": "",
        "main": "webpack.config.js",
        "scripts": {
            "start": "webpack",
            "test": "echo "Error: no test specified" && exit 1"
        },
        "author": "",
        "license": "ISC",
        "devDependencies": {
            "babel-core": "^6.26.0",
            "babel-loader": "^7.1.2",
            "babel-preset-es2015": "^6.24.1",
            "css-loader": "^0.28.7",
            "less": "^2.7.3",
            "less-loader": "^4.0.5",
            "style-loader": "^0.19.0",
            "webpack": "^3.8.1"
        }
    }

    将webpack/build文件夹删除,运行$ npm run start,也能生成webpack/build/app.js




二、简单介绍下package.json中的devDependencies的版本号

  • 以devDependencies中,webapck的版本号为例

    devDependencies的版本号写法 安装依赖的版本
    "webpack": "3.8.1" 等于3.8.1
    "webpack": "~3.8.1" 3.8.x,不会安装3.9.x或者3.7.x
    "webpack": "^3.8.1" 3.x.x,不会安装4.x.x或者2.x.x
    "webpack": ">3.8.1" 大于3.8.1
    "webpack": ">=3.8.1" 大于等于3.8.1
    "webpack": "<=3.8.1" 小于等于3.8.1




三、 webpack-dev-server

轻量级的服务器,可以修改代码后,在页面上看到修改完的效果,详细介绍戳这里

安装依赖
$ npm i webpack-dev-server -g
$ npm i webpack-dev-server --save-dev




案例2

ps:每个案例都是基于前一个案例的内容改造,没有提到的文件和前一个案例内容一样

  1. 运行 $ webpack-dev-server

    如下图
    8

    在浏览器打开连接 http://localhost:8080/src/ ,就能看到案例一的效果了

    webpack/src/index.js

    import "./index.less";
    const fn = () => {
        document.write("hi!")
    }
    fn();

    这个时候在页面能够实时更新,如下图所示
    9

  2. webpack/package.json改造

    webpack/package.json

    {
        "name": "webpack",
        "version": "1.0.0",
        "description": "",
        "main": "webpack.config.js",
        "scripts": {
            "start": "webpack-dev-server",
            "build": "webpack",
            "test": "echo "Error: no test specified" && exit 1"
        },
        "author": "",
        "license": "ISC",
        "devDependencies": {
            "babel-core": "^6.26.0",
            "babel-loader": "^7.1.2",
            "babel-preset-es2015": "^6.24.1",
            "css-loader": "^0.28.7",
            "less": "^2.7.3",
            "less-loader": "^4.0.5",
            "style-loader": "^0.19.0",
            "webpack": "^3.8.1",
            "webpack-dev-server": "^2.9.3"
        }
    }

    10

  3. 可选的参数
    • --content-base: 设定webpack-dev-server的director根目录。如果不进行设定的话,默认是在当前目录下。
    • --quiet: 控制台中不输出打包的信息,开发中一般设置为false,进行 打印,这样查看错误比较方面
    • --no-info: 不显示任何信息
    • --colors: 对信息进行颜色输出
    • --no-colors: 对信息不进行颜色输出
    • --compress: 开启gzip压缩
    • --host <hostname/ip>: 设置ip
    • --port
    • --inline: webpack-dev-server会在你的webpack.config.js的入口配置文件中再添加一个入口,
    • --hot: 开发热替换
    • --open: 启动命令,自动打开浏览器
    • --history-api-fallback: 查看历史url

    下面以“--port”举例

    webpack/package.json

    {
        "name": "webpack",
        "version": "1.0.0",
        "description": "",
        "main": "webpack.config.js",
        "scripts": {
            "start": "webpack-dev-server --port 7777",
            "build": "webpack",
            "test": "echo "Error: no test specified" && exit 1"
        },
        "author": "",
        "license": "ISC",
        "devDependencies": {
            "babel-core": "^6.26.0",
            "babel-loader": "^7.1.2",
            "babel-preset-es2015": "^6.24.1",
            "css-loader": "^0.28.7",
            "less": "^2.7.3",
            "less-loader": "^4.0.5",
            "style-loader": "^0.19.0",
            "webpack": "^3.8.1",
            "webpack-dev-server": "^2.9.3"
        }
    }

    11

    运行 $ npm run start
    12

    浏览器打开页面 http://localhost:7777/src/ ,即可看效果

    webpack-dev-server后写多个参数:webpack-dev-server --hot --inline




四、output和entry

entry:入口文件,简单说就是要打包的文件。

output: 出口文件,简单说就是打包生成的文件。

entry有三种类型的值:字符串、数组、对象。案例一和案例二都是字符串的方式,下面来看下数组(案例三)和对象(案例四)的写法




案例3

entry--值为数组的写法,多个入口对一个出口

新增文件 webpack/src/main.js,如下图
14

webpack/src/main.js

console.log("123")

webpack/webpack.config.js

var webpack = require("webpack");
module.exports = {
    entry: ["./src/index.js", "./src/main.js"], // 入口文件地址
    output: {
        filename: "./build/app.js" // 输出文件地址和名字
    },
    module: {
        loaders: [
            {
                test: /.js$/,  // js-loader
                loader: "babel-loader?presets=es2015"
            },
            {
                test: /.css$/, // css-loader
                loader: "style-loader!css-loader"
            },
            {
                test: /.less/, // less-loader
                loaders: "style-loader!css-loader!less-loader"
            }
        ],
    }
}

运行 $ npm run build,index.js和main.js两个文件最后生成一个webpack/build/app.js文件

运行 $ npm run start,打开 http://localhost:7777/src/ ,可以看到两个文件里的代码都生效了,如下图所示
15




案例4

entry--值为对象的写法,多个入口对多个出口

webpack/webpack.config.js

var webpack = require("webpack");
module.exports = {
    entry: { // 入口文件地址
        app: "./src/index.js",
        main: "./src/main.js"
    },
    output: { // 输出文件地址和名字
        filename: "./build/[name].js"
    },
    module: {
        loaders: [
            {
                test: /.js$/,  // js-loader
                loader: "babel-loader?presets=es2015"
            },
            {
                test: /.css$/, // css-loader
                loader: "style-loader!css-loader"
            },
            {
                test: /.less/, // less-loader
                loaders: "style-loader!css-loader!less-loader"
            }
        ],
    }
}

webpack/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

</body>
<script src="../build/app.js"></script>
<script src="../build/main.js"></script>
</html>

运行 $ npm run build,会生成webpack/build/app.js和webpack/build/main.js

13

将main.js也在index.html里引入一下,就能看见和案例三一样的效果




案例5

output--path和publicPath

webpack/package.json

{
    "name": "webpack",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
        "start": "webpack-dev-server --content-base --inline --hot --port 7777",
        "build": "webpack",
        "test": "echo "Error: no test specified" && exit 1"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "css-loader": "^0.28.7",
        "less": "^2.7.3",
        "less-loader": "^4.0.5",
        "style-loader": "^0.19.0",
        "webpack": "^3.8.1",
        "webpack-dev-server": "^2.9.3"
    }
}

webpack-dev-server的配置参数,可以去 案例2 的 可选的参数 里去找

webpack/webpack.config.js

var webpack = require("webpack");
module.exports = {
    entry: { // 入口文件地址
        app: "./src/index.js",
        main: "./src/main.js"
    },
    output: { // 出口文件
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: "[name].js", // 文件名,name即为entry的key
        publicPath: "/build" // 命令行模式下,一定要配置output.publicPath来指定编译后的包(bundle)的访问位置
    },
    module: {
        loaders: [
            {
                test: /.js$/,  // js-loader
                loader: "babel-loader?presets=es2015"
            },
            {
                test: /.css$/, // css-loader
                loader: "style-loader!css-loader"
            },
            {
                test: /.less/, // less-loader
                loaders: "style-loader!css-loader!less-loader"
            }
        ],
    }
}

__dirname:是一个全局变量,指当前执行脚本所在的目录

path和publicPath的区别:戳这里

运行 $ npm run build 和 $ npm run start (打开 http://localhost:7777/src/ ) 的效果和案例四一样

[name]不一定一定要是文件名,也可以是路径:
filename: "[name]/min.js"
可以自己运行下 $ webpack , 看下生成的文件,这里就不贴图展示了

output里filename有三个值:
· [name]是文件名字是entry的键值。
· [hash]是md5加密的值。
· [chunkhash]可以作为版本号使用。




五、html单独打包

安装依赖
$ npm install html-webpack-plugin --save-dev

可选的配置:

  • title : 用于生成的HTML文件的标题。
  • filename : 用于生成的HTML文件的名称,默认是index.html。也可以指定打包的目录,下面案例7中有介绍。
  • template : 模板的路径。支持加载器,例如 html!./index.html。模板类型可以是html,jade,ejs,hbs等,注意要安装对应的loader
  • inject : 注入选项,有四个值
    • true(默认,script标签位于html文件的 body 底部)
    • ‘head’(script 标签位于 head 标签内)
    • ‘body’(同 true)
    • false(不插入生成的 js 文件,只是单纯的生成一个 html 文件
  • favicon : 给定的图标路径,可将其添加到输出html中。
  • minify : 值为对象或者false,对 html 文件进行压缩,false是默认选项,不压缩。html-minifier详细文档戳这里。
  • hash : true | false。如果是true,会给所有包含的script和css添加一个唯一的webpack编译hash值,类似于我们常用的时间戳。这对于缓存清除非常有用。
  • cache : true(默认) | false 。是否需要缓存,如果传入true,只有在文件变化时才发送(emit)文件。
  • showErrors : true | false 。如果传入true(默认),错误信息将写入html页面。
  • chunks : 主要是针对多入口(entry)文件,默认会在生成的 html 文件中引用所有的 js 文件,也可以指定引入哪些js。
  • excludeChunks : 和chunks刚好相反,指定不需要引入的js。
  • chunksSortMode : 决定了 script 标签的引用顺序。有四个值
    • ‘auto’,默认,内置的排序方式
    • ‘none’,不排序
    • ‘dependency’,按照不同文件的依赖关系来排序
    • {function},可以指定具体排序规则
  • xhtml : 布尔值
    • false,默认
    • true,兼容 xhtml 的模式引用文件




案例6

html-webpack-plugin的基本用法

webpack/package.json

{
    "name": "webpack",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
        "start": "webpack-dev-server --content-base build --inline --hot --port 7777 ",
        "build": "webpack",
        "test": "echo "Error: no test specified" && exit 1"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "css-loader": "^0.28.7",
        "html-webpack-plugin": "^2.30.1",
        "less": "^2.7.3",
        "less-loader": "^4.0.5",
        "style-loader": "^0.19.0",
        "webpack": "^3.8.1",
        "webpack-dev-server": "^2.9.3"
    }
}

webpack-dev-server --content-base
设定webpack-dev-server的director根目录。如果不进行设定的话,默认是在当前目录下。

webpack-dev-server --content-base build
将build目录作为根目录。有一点需要注意的是,webpack-dev-server生成的包并没有放在你的真实目录中,而是放在了内存中。

webpack/webpack.config.js

var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: { // 入口文件地址
        app: "./src/index.js",
        main: "./src/main.js"
    },
    output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: "[name].js" // 文件名,name即为entry的key
    },
    module: {
        loaders: [
            {
                test: /.js$/,  // js-loader
                loader: "babel-loader?presets=es2015"
            },
            {
                test: /.css$/, // css-loader
                loader: "style-loader!css-loader"
            },
            {
                test: /.less/, // less-loader
                loaders: "style-loader!css-loader!less-loader"
            }
        ],
    },
    plugins: [new HtmlWebpackPlugin()]
}

16

运行 $ npm run build ,会发现html被单独打包出来了webpack/build/index.html,如下图所示
17

运行 $ npm run start,打开 http://localhost:7777/ ,就能看到效果。因为我们默认打包后生成的html名就是index(主页面文件),所以这里相当于是打开了 http://localhost:7777/index.html




案例7

html-webpack-plugin的配置--title和filename

webpack/webpack.config.js

var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: { // 入口文件地址
        app: "./src/index.js",
        main: "./src/main.js"
    },
    output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: "[name].js" // 文件名,name即为entry的key
    },
    module: {
        loaders: [
            {
                test: /.js$/,  // js-loader
                loader: "babel-loader?presets=es2015"
            },
            {
                test: /.css$/, // css-loader
                loader: "style-loader!css-loader"
            },
            {
                test: /.less/, // less-loader
                loaders: "style-loader!css-loader!less-loader"
            }
        ],
    },
    plugins: [new HtmlWebpackPlugin({
        title: "demo",
        filename: "demo.html"
    })]
}

18

filename是设置打包好的html文件名,title是设置html的标题。

运行 $ npm run build, 会将html打包webpack/build/demo.html,且页面标题为demo,如下图所示

19

运行 $ npm run start,打开 http://localhost:7777/demo.html 看页面效果

filename其他写法:(下面介绍两种,大家自己试一下)

  • filename: "./dist/demo.html"。 则html会被打包成webpack/build/dist/demo.html
  • filename: __dirname + "/dist/demo.html"。 则html会被打包到webpack/dist/demo.html




案例8

html-webpack-plugin的配置--template和chunks,生成多个html

新建文件 webpack/src/main.html,如下图所示
20

webpack/src/main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>main</title>
</head>
<body>

</body>
</html>

webpack/src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>

</body>
</html>

webpack/webpack.config.js

var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: { // 入口文件地址
        app: "./src/index.js",
        main: "./src/main.js"
    },
    output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: "[name].js" // 文件名,name即为entry的key
    },
    module: {
        loaders: [
            {
                test: /.js$/,  // js-loader
                loader: "babel-loader?presets=es2015"
            },
            {
                test: /.css$/, // css-loader
                loader: "style-loader!css-loader"
            },
            {
                test: /.less/, // less-loader
                loaders: "style-loader!css-loader!less-loader"
            }
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: "demo.html", // 生成的的html文件名
            template: "./src/index.html", // 被打包的html路径
            chunks: ["app"] // 需要引入的js
        }),
        new HtmlWebpackPlugin({
            filename: "main.html",
            template: "./src/main.html",
            chunks: ["main"]
        })
    ]
}

运行 $ npm run build,生成的文件如下所示
21

webpack/src/index.html打包生成webpack/build/demo.html,并且引入的js是app.js。 webpack/src/main.html打包生成的是webpack/build/main.html,js引入的是main.js。

template:需要打包的html的文件路径
chunks:是一个数组,里面的值对应entry里的key,可以写多个,例如 chunks: ["app","main"]

运行 $ npm run start, 分别打开 http://localhost:7777/main.html 和 http://localhost:7777/demo.html 可以看到页面效果




六、css单独打包

安装依赖 $ npm install extract-text-webpack-plugin --save-dev

new ExtractTextPlugin() 和 ExtractTextPlugin.extract() 详细介绍戳这里

  1. ExtractTextPlugin.extract(),有三个参数:
    • 第一个参数是可选参数,传入一个loader,当css样式没有被抽取的时候可以使用该loader;
    • 第二个参数则是用于编译解析的css文件loader,很明显这个是必须传入的,就像上述例子的css-loader;
    • 第三个参数是一些额外的备选项,貌似目前只有传入publicPath,用于当前loader的路径。
  2. new ExtractTextPlugin([id: string], filename: string, [options])
    • [id: string]:该插件实例的唯一标志,一般是不会传的,其自己会生成
    • filename: 文件名,包含[name]、[id]、[contenthash]
      • [name]:将会和entry中的chunk的名字一致
      • [id]:将会和entry中的chunk的id一致
      • [contenthash]:根据内容生成hash值
    • options
      • allchunk: 是否将所有额外的chunk都压缩成一个文件
      • disable:禁止使用插件




案例9

新建文件webpack/src/main.css

webpack/src/main.css

body {
    background: red;
}

webpack/src/main.js

import "./main.css";
console.log("123")

webpack/webpack.config.js

var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    entry: { // 入口文件地址
        app: "./src/index.js",
        main: "./src/main.js"
    },
    output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: "[name].js" // 文件名,name即为entry的key
    },
    module: {
        loaders: [
            {
                test: /.js$/,  // js-loader
                loader: "babel-loader?presets=es2015"
            },
            {
                test: /.css$/, // css-loader
                loader: ExtractTextPlugin.extract(["css-loader"])
            },
            {
                test: /.less/, // less-loader
                loaders: ExtractTextPlugin.extract([ "css-loader", "less-loader" ])
            }
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: "demo.html", // 生成的的html文件名
            template: "./src/index.html", // 被打包的html路径
            chunks: ["app"] // 需要引入的js
        }),
        new HtmlWebpackPlugin({
            filename: "main.html",
            template: "./src/main.html",
            chunks: ["main"]
        }),
        new ExtractTextPlugin("[name].css")
    ]
}

23

这里写了css和less两种文件的打包,并生成对应的名字

运行 $ npm run build,效果如下

22

在index.js里引入的index.less,最后生成的app.css,并且在index.html中引用了。在main.js里引入的main.css,打包后生成main.css,并且在main.html中引用。

运行 $ npm run start, 分别打开 http://localhost:7777/main.html 和 http://localhost:7777/demo.html 可以看到页面效果。

这个时候会发现,如果修改js页面还是会自动刷新,如果修改css或者less,页面需要手动刷新才会看到最新的效果




七、图片的处理

安装依赖
$ npm i url-loader --save-dev
$ npm i file-loader --save-dev




案例10

新增 webpack/src/images/Ahri.jpg
Ahri

新增 webpack/src/images/Minions.jpg
Minions

webpack/src/index.less

body {
    height: 500px;
    background: url("./images/Ahri.jpg") no-repeat center;
}

webpack/src/main.css

body {
    background: url("./images/Minions.jpg") no-repeat;
}

webpack/webpack.config.js

我要说两句: (0人参与)

发布