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

    如下图所示

    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

    入下图所示

    然后就看到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‘
                }
            ],
        }
    }

    分析如下图

    安装依赖

    • 安装webpack依赖

      $ npm i webpack --save-dev

      $ npm i [email protected] --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文件,就会发现多了一部分内容,如下图所示

  4. 运行 $ webpack

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

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

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

    如下图所示

    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

    如下图

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

    webpack/src/index.js

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

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

  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"
        }
    }

  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"
        }
    }

    运行 $ npm run start

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

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


四、output和entry

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

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

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


案例3

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

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

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/ ,可以看到两个文件里的代码都生效了,如下图所示


案例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

将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()]
}

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

运行 $ 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‘
    })]
}

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

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

运行 $ 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,如下图所示

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,生成的文件如下所示

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.htmlhttp://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")
    ]
}

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

运行 $ npm run build,效果如下

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

运行 $ npm run start, 分别打开 http://localhost:7777/main.htmlhttp://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

新增 webpack/src/images/Minions.jpg

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

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‘ ])
            },
            {
                test: /\.(png|jpg)$/, // img-loader
                loader: ‘url-loader?limit=8192&name=images/[hash:8].[name].[ext]‘
            }
        ],
    },
    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({
            filename: ‘[name].css‘
        })
    ]
}

运行 $ npm run start

打开 http://localhost:7777/demo.html ,效果如下

打开 http://localhost:7777/main.html ,效果如下

运行 $ npm run build,如下所示

分析如下

  1. 除了png和jpg外,还可以添加gif等,以“|”分隔。
  2. limit=8192,图片小于8192字节时以,转为base64引入,大于8192字节时,调用file-loader打包生成文件
  3. name=images/[hash:8].[name].[ext],“ images/ ”指定图片打包到文件夹webpack/build/images,“ [hash:8] ”指8位 hash 值

可以自己尝试下这种打包出来的结果:

{
    test: /\.(png|jpg)$/, // img-loader
    loader: ‘url-loader?limit=8192‘
}

效果如下


八、引入jq

npm i jquery --save-dev


案例11

webpack/src/index.js

import ‘./index.less‘;
import $ from ‘jquery‘;
$(‘body‘).prepend(‘hehe‘);

这样运行 $ npm run build,jquery被打包到app.js里了


九、CommonsChunkPlugin 打包公共文件

new webpack.optimize.CommonsChunkPlugin({
    name: xx, // 对应entry的key
    filename: xx, // 输出的文件名,如果不写这个则以name为输出的文件名
    chunks: xx // 只有在这个文件中引入的模块才能被打包
    minChunks: xx, // 符合引用次数的则被打包
})

案例12

单一入口,分文件输出

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‘ ])
            },
            {
                test: /\.(png|jpg)$/, // img-loader
                loader: ‘url-loader?limit=8192&name=images/[hash:8].[name].[ext]‘
            }
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: ‘demo.html‘, // 生成的的html文件名
            template: ‘./src/index.html‘, // 被打包的html路径
            chunks: [‘app‘, ‘chunk‘] // 需要引入的js
        }),
        // new HtmlWebpackPlugin({
        //     filename: ‘main.html‘,
        //     template: ‘./src/main.html‘,
        //     chunks: [‘main‘]
        // }),
        new ExtractTextPlugin({
            filename: ‘[name].css‘
        }),
        new webpack.optimize.CommonsChunkPlugin("chunk")
    ]
}

$ npm run build, 打包出来的结果如下:

这里注意,chunk.js一定要在app.js之前引入


案例13

多入口,分文件输出,jquery单独打包

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‘,
        jquery: [ "jquery" ]
        // 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‘ ])
            },
            {
                test: /\.(png|jpg)$/, // img-loader
                loader: ‘url-loader?limit=8192&name=images/[hash:8].[name].[ext]‘
            }
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: ‘demo.html‘, // 生成的的html文件名
            template: ‘./src/index.html‘, // 被打包的html路径
            chunks: [‘app‘, ‘jquery‘] // 需要引入的js
        }),
        // new HtmlWebpackPlugin({
        //     filename: ‘main.html‘,
        //     template: ‘./src/main.html‘,
        //     chunks: [‘main‘]
        // }),
        new ExtractTextPlugin({
            filename: ‘[name].css‘
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: ‘jquery‘
        })
    ]
}

运行 $ npm run build, 效果如下

通过webpack.optimize.CommonsChunkPlugin,将jquery单独打包到jquery.js中。如果不写这部分,app.js中也会被打包入jquery,大家可以自己尝试下。


案例14

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‘,
        jquery: [ "jquery" ]
    },
    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‘ ])
            },
            {
                test: /\.(png|jpg)$/, // img-loader
                loader: ‘url-loader?limit=8192&name=images/[hash:8].[name].[ext]‘
            }
        ],
    },
    plugins: [ // 插件
        new HtmlWebpackPlugin({
            filename: ‘demo.html‘, // 生成的的html文件名
            template: ‘./src/index.html‘, // 被打包的html路径
            chunks: [‘app‘, ‘jquery‘] // 需要引入的js
        }),
        new HtmlWebpackPlugin({
            filename: ‘main.html‘,
            template: ‘./src/main.html‘,
            chunks: [‘main‘]
        }),
        new ExtractTextPlugin({
            filename: ‘[name].css‘
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: ‘jquery‘,
            chunks: [‘app‘] // 在app.js中引用的才被打包
        })
    ]
}

$ npm run build, main.js和app.js中均为打包入jquery,jquery被单独打包,并且仅在demo.html中引用。


十、js压缩

这里介绍两种方式大家自己运行 $ npm run build 试试,对比下压缩前后的效果

  1. new webpack.optimize.UglifyJsPlugin()

    webpack/webpack.config.js的plugins添加如下

    module.exports = {
        plugins: [
            new webpack.optimize.UglifyJsPlugin({
                compress: {
                    warnings: false
                }
            })
        ]
    }
  2. webpack -p

    webpack/package.json的scripts修改如下

    "scripts": {
        "build": "webpack -p",
    },

十一、自动添加css前缀 postcss-loader

类似下面这种需要添加浏览器前缀等兼容的情况,每次自己写太麻烦,可以用postcss-loader帮助我们完成这些功能

display: -webkit-box;
display: -ms-flexbox;
display: flex;

这里综合上面所讲的内容,从头写一个新的demo(简单的留言板效果), 效果如下

demo涉及到上面没有讲过的内容,如下:


案例15

新建项目文件夹 webpackDemo,文件目录如下

运行 $ npm init。

安装以下依赖 :

babel-core

babel-loader

babel-preset-es2015

css-loader

extract-text-webpack-plugin

file-loader

html-webpack-plugin

jquery

less

less-loader

style-loader

url-loader

webpack

webpack-dev-server

webpackDemo/src/index.html

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

webpackDemo/src/css/reset.less

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: ‘‘;
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}
input, button {
    outline:none;
}

webpackDemo/src/css/index.less

@import ‘reset.less‘;
.wrapper {
    margin: 50px auto;
    border: 1px solid #000;
    width: 400px;
    height: 500px;
    background: lightpink;
}

webpackDemo/src/index.js

import ‘../src/css/index.less‘;
import $ from ‘jquery‘;
$(‘.wrapper‘).append(‘您好‘);

webpackDemo/package.json

{
    "name": "webpackdemo",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
        "start": "webpack-dev-server --content-base build --inline --hot",
        "build": "webpack -p",
        "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",
        "extract-text-webpack-plugin": "^3.0.2",
        "file-loader": "^1.1.5",
        "html-webpack-plugin": "^2.30.1",
        "jquery": "^3.2.1",
        "less": "^2.7.3",
        "less-loader": "^4.0.5",
        "style-loader": "^0.19.0",
        "url-loader": "^0.6.2",
        "webpack": "^3.10.0",
        "webpack-dev-server": "^2.9.5"
    }
}

webpackDemo/webpack.config.js

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

module.exports = {
    entry: { // 入口文件地址
        index: ‘./src/index.js‘,
        vendor: [ "jquery" ]
    },
    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‘ ])
            },
            {
                test: /\.(png|jpg)$/, // img-loader
                loader: ‘url-loader?limit=8192&name=images/[hash:8].[name].[ext]‘
            }
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: ‘index.html‘, // 生成的的html文件名
            template: ‘./src/index.html‘, // 被打包的html路径
            chunks: [‘index‘, ‘vendor‘] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({
            filename: ‘[name].css‘
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: ‘vendor‘ // 对应entry的key
        })
    ]
}

运行 $ npm run start, 打开 http://localhost:8080/ ,效果如下:

下面写banner(输入框和发送按钮)部分,先写一个简单的js

新建 webpackDemo/src/js/banner.js

webpackDemo/src/js/banner.js

export default function ($wrapper) {
  $wrapper.append(‘banner‘);
}

webpackDemo/src/index.js

import ‘../src/css/index.less‘;
import $ from ‘jquery‘;
import bannerRender from ‘../src/js/banner‘;

const $wrapper = $(‘.wrapper‘);

const init = () => {
  bannerRender($wrapper);
}

init();

效果如下:

下面写banner部分的html部分和css部分

安装依赖 $ npm i atpl-loader postcss-loader --save-dev

新建

webpackDemo/src/tpl/banner.atpl

webpackDemo/src/css/banner.less

webpackDemo/postcss.config.js

webpackDemo/postcss.config.js

module.exports = {
    plugins: [
        require(‘autoprefixer‘)
    ]
}

webpackDemo/webpack.config.js

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

module.exports = {
    entry: { // 入口文件地址
        index: ‘./src/index.js‘,
        vendor: [ "jquery" ]
    },
    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 postcss-loader
                loader: ExtractTextPlugin.extract(‘css-loader!postcss-loader‘)
            },
            {
                test: /\.less/, // less-loader postcss-loader
                loaders: ExtractTextPlugin.extract(‘css-loader!less-loader!postcss-loader‘)
            },
            {
                test: /\.(png|jpg)$/, // img-loader
                loader: ‘url-loader?limit=8192&name=images/[hash:8].[name].[ext]‘
            },
            {
                test: /\.atpl?$/, // atpl
                loader: ‘atpl-loader‘,
            }
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: ‘index.html‘, // 生成的的html文件名
            template: ‘./src/index.html‘, // 被打包的html路径
            chunks: [‘index‘, ‘vendor‘] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({
            filename: ‘[name].css‘
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: ‘vendor‘ // 对应entry的key
        })
    ]
}

webpackDemo/src/tpl/banner.atpl

<div class="banner-wrap">
  <input class="ipt" placeholder="在这里输入留言内容" />
  <button class="btn">发送</button>
</div>

webpackDemo/src/css/banner.less

.banner-wrap {
    height: 50px;
    background: #fff;
    display: flex;
    .ipt {
        flex: 1;
        border: 0;
        padding: 0 10px;
        box-sizing: border-box;
        font-size: 16px;
    }
    .btn {
        border: 0;
        width: 50px;
        border-radius: 0;
        color: #fff;
        font-size: 16px;
        background: #666;
    }
}

webpackDemo/src/js/banner.js

import ‘../css/banner.less‘;
import bannerTpl from ‘../tpl/banner.atpl‘;

export default function ($wrapper) {
  $wrapper.append(bannerTpl({}));
}

运行 $ npm run start , 打开 http://localhost:8080/index.html , 效果如下

下面写留言区域的部分

新建

webpackDemo/src/tpl/message.atpl

webpackDemo/src/css/message.less

webpackDemo/src/js/message.js

webpackDemo/src/tpl/message.atpl

<ul class="message-wrap">
  <li>大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!大家好!</li>
  <li>留言6666666</li>
  <li>留言555555</li>
  <li>留言44444444</li>
  <li>留言3333333</li>
  <li>留言222222222</li>
  <li>留言11111111</li>
</ul>

webpackDemo/src/css/message.less

.message-wrap {
  padding: 25px;
  height: 400px;
  overflow-y: auto;
  overflow-x: hidden;
  li {
    border-bottom: 1px dashed lightcoral;
    padding: 10px 0;
    line-height: 1.5;
  }
}

webpackDemo/src/js/message.js

import ‘../css/message.less‘;
import messageTpl from ‘../tpl/message.atpl‘;

export default function ($wrapper) {
  $wrapper.append(messageTpl({}));
}

webpackDemo/src/index.js

import ‘../src/css/index.less‘;
import $ from ‘jquery‘;
import bannerRender from ‘../src/js/banner‘;
import messageRender from ‘../src/js/message‘;

const $wrapper = $(‘.wrapper‘);

const init = () => {
  bannerRender($wrapper); // 引入banner部分
  messageRender($wrapper); // 引入message部分
}

init();

运行 $ npm run start , 打开 http://localhost:8080/index.html , 效果如下

接下来写留言功能

webpackDemo/src/js/banner.js

import ‘../css/banner.less‘;
import bannerTpl from ‘../tpl/banner.atpl‘;

// html
const render = ($wrapper) => {
    $wrapper.append(bannerTpl({}));
}

// 事件
const bindEvents = ($wrapper) => {
    // 点击发送按钮发送输入框内容
    $wrapper.on(‘click‘, ‘.btn‘, () => {
        const $ipt = $wrapper.find(‘.ipt‘);
        const $messageWrap = $wrapper.find(‘.message-wrap‘);
        const val = $ipt.val();
        // 当input有内容的时候才允许发送
        if ($ipt.length && val.length) {
            $messageWrap.prepend(`<li>${val}</li>`);
            // 发送完后清空input的val
            $ipt.val(‘‘);
        }
    })
}

export default function ($wrapper) {
    render($wrapper);
    bindEvents($wrapper);
}

运行 $ npm run start , 打开 http://localhost:8080/index.html,就能看到如下效果了

时间: 2024-08-02 05:05:04

webpack构建项目的相关文章

Vue2+VueRouter2+webpack 构建项目实战(二):目录以及文件结构

通过上一篇博文<Vue2+VueRouter2+webpack 构建项目实战(一):准备工作>,我们已经新建好了一个基于vue+webpack的项目.本篇文章详细介绍下项目的结构. 项目目录以及文件结构 如图所示: 如上图所示,自动构建的vue项目的结构就是这样. 目录/文件 说明 build 这个是我们最终发布的时候会把代码发布在这里,在开发阶段,我们基本不用管. config 配置目录,默认配置没有问题,所以我们也不用管 node_modules 项目开发依赖的一些模块 src 开发目录(

[F2016061802] NodeJS之旅-使用webpack构建项目时代码正确但编译出错

遇到这个问题前,我对webpack还不算太熟,仅仅限于用它来编译ES6代码,代码写多了,问题也就来了. 一开始用NodeJS写些小项目,用的模块并不多,遇到些报错问题,改改也就通过了.然而,随着用的第三方模块增多,用webpack构建项目时出现错误的次数越来越多,最奇怪的是:代码检查了十几遍,明明任何错误都没有,编译却通不过.最后只能硬着头皮去看编译后的代码才明白问题出在哪里! 对于webpack,它是自动把依赖都输出到目标文件中.比如: import koa from 'koa' 构建后的输出

Vue2+VueRouter2+webpack 构建项目实战(三):配置路由,运行页面

制作.vue模板文件 通过前面的两篇博文的学习,我们已经建立好了一个项目.问题是,我们还没有开始制作页面.下面,我们要来做页面了. 我们还是利用 http://cnodejs.org/api 这里公开的api来做项目.不过本章节不涉及调用接口等内容.这里,我们假设我们的项目是做俩页面,一个列表页面,一个内容页面.列表页面有分页等,内容页面展示. 因此,我们需要两个模板文件. 我们在src/page目录下面新建两个文件,分别是index.vue和content.vue index.vue代码: <

webpack 构建项目入门

参考http://www.cnblogs.com/eyunhua/p/6398885.html --------------------------------------------------------------------- 已安装node.js,利用npm输入命令全局安装(-g) npm install webpack -g 安装完后,输入 webpack -v  查看当前webpack的版本号. 正式使用Webpack  进入项目目录,输入命令:npm init,生成package

Vue2+VueRouter2+webpack 构建项目实战(五):配置子路由

前言 通过前面几章的实战,我们已经顺利的构建项目,并且从API接口获取到数据并且渲染出来了.制作更多的页面,更复杂的应用,就是各位自己根据自己的项目去调整的事情了. 本章讲一下如何配置子路由,因为我们的项目不可能只有一个页面,而是由众多页面构成的. 新建子路由页面 在第二节中,我们新建了一个src/frame/subroute.vue的子页面.当时是留空放在那里的.这里,我们给它填写上内容,代码如下: <template> <div> <div class="mai

[F2016061801] NodeJS之旅-使用webpack构建项目时遇到__dirname路径不对

最近准备用koa搭建个人博客网站,但在开发前就遇到了很多头疼的问题,比如用koa-views渲染模板,代码和官网的例子一模一样,但就是渲染不出来,提示找不到模板路径,真是头疼,研究了一天也没解决. 现在解决了,索性把解决方法简单记录一下,当时网上搜索了很久也找不到原因,最后还是在webpack官网闲逛的时候发现了问题的根源,所以说平时多逛逛技术网站还是有帮助的. 用koa-views渲染模板时配置的第一个参数是模板文件夹根路径,koa-views仓库里提供的路径是: views(__dirnam

vue+webpack构建项目

1,下载node 在node官网上下载:https://nodejs.org/en/ 如果已经下载了,可以查看一下版本 cmd中输入node -v 2,下载npm 可以直接下载npm包管理工具或者安装淘宝镜像 如果已经下载了,可以查看一下版本 cmd中输入npm -v (注意:这个必须要3.0.0以上) 3,安装脚手架vue-cli npm install -g vue-cli 这个必须安装在全局中 4,新建一个文件夹demo vue init wenpack demo 这个会出现一些需要自己填

Vue2+VueRouter2+webpack 构建项目实战(四):接通api,渲染列表

通过前面几篇教程,我们已经顺利搭建起来了,并且已经组建好路由了.本章节,我们需要做一个列表页面,然后利用获取 http://cnodejs.org/api 的公开API,渲染出来. 我们打开src/page/index.vue文件,在这里写入下面的代码: <template> <div> <h1 class="logo">cnodejs Api Test</h1> <ul class="list"> <

webpack构建项目连接本机IP仍无法访问问题

通过连接IP地址,确定连接成功后仍无法访问本机运行项目,需要对项目配置进行修改,有两种情况: 第一种是在config/index.js,把module.exports={}中找到 host:'localhost'改为host:'0.0.0.0',保存之后重新启动项目试试(如果没有找到请看第二条). 第二种是在package.json中,找到如下: 并将其改为 host 0.0.0.0 --port 8080 这两种方式都是将host改为0.0.0.0,只是配置的地方不一样而已 原文地址:http