webpack——快速入门【一】

2024-08-16 10:21:44 浏览数 (3)

学习webpack

https://github.com/webproblem/learning-article#webpack

https://github.com/lengziyu/learn-webpack

先跟着下面这个例子来做一遍,因为版本原因如果你跟着原文可能会出错,所以我会在这里修复原文中的错误,本文使用的是4.29.3版本

https://segmentfault.com/a/1190000006178770?utm_source=tag-newest

请结合官方文档来进行学习

https://www.webpackjs.com/concepts/#入口-entry-

https://webpack.js.org/configuration/dev-server#devserver

什么是webpack

webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

为什么使用webpack

① 模块化开发(import,require)

② 预处理(Less,Sass,ES6,TypeScript……)

③ 主流框架脚手架支持(Vue,React,Angular)

④ 庞大的社区(资源丰富,降低学习成本)

总之一句话,方便快捷便于我们快速的开发。

快速开始

根据整理的资料进行实际操作,并修正版本更新造成一些命令引发的错误,我用的工具是gitbash,平台为windows平台,安装都只是安装到项目文件夹中没有进行全局安装

创建空文件夹

代码语言:javascript复制
$ mkdir webpack

$ cd webpack

$ mkdir {app,public}

$ ll
total 0
drwxr-xr-x 1 Administrator 197121 0 二月 13 13:23 app/
drwxr-xr-x 1 Administrator 197121 0 二月 13 13:23 public/

安装webpack

进入文件根目录,然后安装webpack到此项目中,这个用的是淘宝镜像,这样可以加快安装速度。

npm指向淘宝镜像

代码语言:javascript复制
$ cnpm install --save-dev webpack
platform unsupported webpack@4.29.3 › watchpack@1.6.0 › chokidar@2.1.1 › fsevents@^1.2.7 Package require os(darwin) not compatible with your platform(win32)
[fsevents@^1.2.7] optional install error: Package require os(darwin) not compatible with your platform(win32)
√ Installed 1 packages
√ Linked 267 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-06): 6 packages (detail see file C:UsersAdministrator.KINGDesktopwebpacknode_modules.recently_updates.txt)
√ All packages installed (292 packages installed from npm registry, used 5s(network 5s), speed 100.79kB/s, json 268(498kB), tarball 0B)

创建文件

cd到app文件夹下创建greeter.js和main.js

代码语言:javascript复制
$ cd app

$ vi greeter.js

$ vi main.js

greeter.js

Greeter.js中定义一个返回包含问候信息的html元素的函数,并依据CommonJS规范导出这个函数为一个模块

代码语言:javascript复制
module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "小哥哥,快来啊,快活啊";
  return greet;
};

main.js

main.js文件中我们写入下述代码,用以把Greeter模块返回的节点插入页面。

代码语言:javascript复制
const greeter = require('./Greeter.js');
document.querySelector("#root").appendChild(greeter());

cd到public下面创建index.html

代码语言:javascript复制
$ cd ..

$ cd public/
$ vi index.html

index.html

其中bundle.js为打包后的js文件名称

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Webpack Sample Project</title>
  </head>
  <body>
    <div id='root'>
    </div>
    <script src="bundle.js"></script>
  </body>
</html>

打包

这里安装使用的就是非全局安装,所以打包也使用非全局打包

代码语言:javascript复制
$ node_modules/.bin/webpack app/main.js -o public/bundle.js
Hash: c6d5fc7966695da6f6cd
Version: webpack 4.29.3
Time: 358ms
Built at: 2019-02-13 12:54:49
Asset Size Chunks Chunk Names
bundle.js 1.09 KiB 0 [emitted] main
Entrypoint main = bundle.js
[0] ./app/main.js 255 bytes {0} [built]
[1] ./app/Greeter.js 304 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

进入public打开index.html即可查看效果

创建配置文件

在根目录下创建webpack.config.js文件,主要配置入口文件和打包后文件

代码语言:javascript复制
module.exports = {
  entry:  __dirname   "/app/main.js",//已多次提及的唯一入口文件
  output: {
    path: __dirname   "/public",//打包后的文件存放的地方
    filename: "bundle.js"//打包后输出文件的文件名
  }
}

:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。

修改greeter.js

就是改了下文字内容~

代码语言:javascript复制
module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "We still hava a long way to go.";
  return greet;
};

重新打包

这时候就很简单了,当然如果全局安装的话,直接webpack就可以了

代码语言:javascript复制
$ node_modules/.bin/webpack
Hash: 9725aade1d1273904ee2
Version: webpack 4.29.3
Time: 364ms
Built at: 2019-02-13 14:19:38
    Asset     Size  Chunks             Chunk Names
bundle.js  1.1 KiB       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./app/main.js 255 bytes {0} [built]
[1] ./app/Greeter.js 314 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

自定义打包命令

npm进行配置后可以在命令行中使用简单的npm start命令来替代上面略微繁琐的命令。在package.json中对scripts对象进行相关设置

如果没有这个package.json文件不要慌,直接npm init初始化一个就可以了,现在开始配置。

反正是测试不发布的,所以可以直接回车即可。

代码语言:javascript复制
$ npm init

打开package.json修改scripts对象添加以下内容

我这里是非全局安装所有添加的是node_modules/.bin/webpack,全局安装的直接添加webpack即可

代码语言:javascript复制
"start":"node_modules/.bin/webpack"  

完整的json文件如下

代码语言:javascript复制
{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "dependencies": {
    "webpack-cli": "^3.2.3",
    "webpack": "^4.29.3"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "start":"node_modules/.bin/webpack"  
  },
  "author": "",
  "license": "ISC"
}

再次修改greeter.js

代码语言:javascript复制
module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "Hello world";
  return greet;
};

使用自定义的命令打包

代码语言:javascript复制
$ npm start

> webpack@1.0.0 start D:wampwwwwebpack
> webpack

Hash: 1b28a19fd8d2277de6f0
Version: webpack 4.29.3
Time: 376ms
Built at: 2019-02-13 14:31:57
    Asset      Size  Chunks             Chunk Names
bundle.js  1.08 KiB       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./app/main.js 255 bytes {0} [built]
[1] ./app/Greeter.js 294 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

其中有个关于npm的小知识,需要各位到原文去查看,毕竟我们也是从人家那边学习,不给赞赏给给访问也可以啊

生成Source Maps

webpack的配置文件中配置source maps,需要配置devtool,它有以下四种不同的配置选项,各具优缺点,描述如下:

devtool选项

配置结果

source-map

在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度;

cheap-module-source-map

在一个单独的文件中生成一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便;

eval-source-map

使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定不要启用这个选项;

cheap-module-eval-source-map

这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点;

上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对打包后的文件的的执行有一定影响。

对小到中型的项目中,eval-source-map是一个很好的选项,再次强调你只应该开发阶段使用它,我们继续对上文新建的webpack.config.js,进行如下配置:

代码语言:javascript复制
module.exports = {
    devtool: 'eval-source-map',
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/public",
        filename: "bundle.js"
    }
}

可能有的同学一直看到了这个警告

代码语言:javascript复制
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

这是什么呢,因为我们没有在webpack.config.js中配置模式造成了,我们顺手也配置下吧

代码语言:javascript复制
development 开发环境
代码语言:javascript复制
production  生产环境
代码语言:javascript复制
module.exports = {
    mode:'development',
    devtool: 'eval-source-map',
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/public",
        filename: "bundle.js"
    }
}

构建本地服务器

可以让浏览器监听你的代码的修改,并自动刷新显示修改后的结果

代码语言:javascript复制
$ cnpm install --save-dev webpack-dev-server
platform unsupported webpack-dev-server@3.1.14 › chokidar@2.1.1 › fsevents@^1.2.7 Package require os(darwin) not compatible with your platform(win32)
[fsevents@^1.2.7] optional install error: Package require os(darwin) not compatible with your platform(win32)
√ Installed 1 packages
√ Linked 429 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-06): 7 packages (detail see file D:wampwwwwebpacknode_modules.recently_updates.txt)
√ All packages installed (472 packages installed from npm registry, used 19s(network 19s), speed 43.94kB/s, json 430(799.49kB), tarball 36.44kB)

修改配置文件webpack.config.js

代码语言:javascript复制
module.exports = {
    mode:'development',
    devtool: 'eval-source-map',
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",//本地服务器所加载的页面所在的目录
        historyApiFallback: true,//不跳转
        inline: true//实时刷新
  }
}

package.json中的scripts对象中添加如下命令,用以开启本地服务器:

代码语言:javascript复制
{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "dependencies": {
    "webpack-cli": "^3.2.3",
    "webpack": "^4.29.3"
  },
  "devDependencies": {
    "webpack-dev-server": "^3.1.14"
  },
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "start": "node_modules/.bin/webpack",
    "server": "webpack-dev-server --open"
  },
  "author": "",
  "license": "ISC"
}

运行服务

代码语言:javascript复制
$ npm run server

> webpack@1.0.0 server D:wampwwwwebpack
> webpack-dev-server --open

i 「wds」: Project is running at http://localhost:8081/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from ./public
i 「wds」: 404s will fallback to /index.html
i 「wdm」: wait until bundle finished: /
i 「wdm」: Hash: a3f5179d4ce1ace1f048
Version: webpack 4.29.3
Time: 744ms
Built at: 2019-02-13 14:56:40
    Asset     Size  Chunks             Chunk Names
bundle.js  867 KiB    main  [emitted]  main
Entrypoint main = bundle.js
[0] multi ./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client?http://localhost:8081 ./app/main.js 40 bytes {main} [built]
[./app/Greeter.js] 294 bytes {main} [built]
[./app/main.js] 255 bytes {main} [built]
[./node_modules/_ansi-html@0.0.7@ansi-html/index.js] 4.16 KiB {main} [built]
[./node_modules/_ansi-regex@2.1.1@ansi-regex/index.js] 135 bytes {main} [built]
[./node_modules/_html-entities@1.2.1@html-entities/index.js] 231 bytes {main} [built]
[./node_modules/_loglevel@1.6.1@loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/_sockjs-client@1.3.0@sockjs-client/dist/sockjs.js] 180 KiB {main} [built]
[./node_modules/_strip-ansi@3.0.1@strip-ansi/index.js] 161 bytes {main} [built]
[./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client/index.js?http://localhost:8081] ./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client?http://localhost:8081 7.78 KiB {main} [built]
[./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client/overlay.js] 3.58 KiB {main} [built]
[./node_modules/_webpack-dev-server@3.1.14@webpack-dev-server/client/socket.js] 1.05 KiB {main} [built]
[./node_modules/url/url.js] 22.8 KiB {main} [built]
[./node_modules/webpack/hot sync ^./log$] (webpack)/hot sync nonrecursive ^./log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 75 bytes {main} [built]
      12 hidden modules
i 「wdm」: Compiled successfully.

Loader

配置loader之前,我们把Greeter.js里的问候消息放在一个单独的JSON文件里,并通过合适的配置使Greeter.js可以读取该JSON文件的值,各文件修改后的代码如下:

在app文件夹下新增一个greet.json文件

greet.json

代码语言:javascript复制
{
  "greetText": "Hi there and greetings from JSON!"
}

greeter.js

代码语言:javascript复制
var config = require('./greet.json');
module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = config.greetText;;
  return greet;
};

自动编译的结果显示

Babel

Babel其实是一个编译JavaScript的平台,它可以编译代码帮你达到以下目的:

  • 让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器完全支持;
  • 让你能使用基于JavaScript进行了拓展的语言,比如React的JSX;

安装依赖包

新版本的要求依赖包必须是7的,不然是会报错的,报错不可怕,只要看信息总会解决的!

代码语言:javascript复制
$ cnpm install --save-dev babel-core babel-loader@7  babel-preset-env babel-preset-react
√ Installed 4 packages
√ Linked 121 latest versions
√ Run 0 scripts
peerDependencies WARNING babel-loader@* requires a peer of @babel/core@^7.0.0 but none was installed
Recently updated (since 2019-02-06): 3 packages (detail see file D:wampwwwwebpacknode_modules.recently_updates.txt)
√ All packages installed (113 packages installed from npm registry, used 4s(network 4s), speed 329.85kB/s, json 125(427.86kB), tarball 873.08kB)

配置webpack.config.js文件

代码语言:javascript复制
module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [{
            test: /(.jsx|.js)$/,
            use: {
                loader: "babel-loader",
                options: {
                    presets: [
                        "env", "react"
                    ]
                }
            },
            exclude: /node_modules/
        }]
    }
}

现在你的webpack的配置已经允许你使用ES6以及JSX的语法了。继续用上面的例子进行测试,不过这次我们会使用React,记得先安装 React 和 React-DOM

我只想学下webpack你还给我赠送了react......

代码语言:javascript复制
$ cnpm install --save react react-dom
√ Installed 2 packages
√ Linked 5 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-06): 5 packages (detail see file D:wampwwwwebpacknode_modules.recently_updates.txt)
√ All packages installed (5 packages installed from npm registry, used 1s(network 1s), speed 901.37kB/s, json 7(32.33kB), tarball 1.21MB)

接下来我们使用ES6的语法,更新greeter.js并返回一个React组件

代码语言:javascript复制
import React, {Component} from 'react'
import config from './config.json';

class Greeter extends Component{
  render() {
    return (
      <div>
        {config.greetText}
      </div>
    );
  }
}

export default Greeter

修改main.js如下,使用ES6的模块定义和渲染Greeter模块

代码语言:javascript复制
import React from 'react';
import {render} from 'react-dom';
import Greeter from './greeter';

render(<Greeter />, document.getElementById('root'));

然后重新打包

代码语言:javascript复制
$ npm start

> webpack@1.0.0 start D:wampwwwwebpack
> webpack

Hash: bcd934684f9507b2fc78
Version: webpack 4.29.3
Time: 2240ms
Built at: 2019-02-13 16:13:51
    Asset      Size  Chunks             Chunk Names
bundle.js  2.16 MiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/Greeter.js] 5.28 KiB {main} [built]
[./app/greet.json] 58 bytes {main} [built]
[./app/main.js] 1.23 KiB {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
      11 hidden modules

分开配置

虽然可以在webpack.config.js中配置,但是babel的配置项还是很多的,所以我们单独命名一个.babelrc的配置文件

webpack会自动调用.babelrc的配置文件

webpack.config.js

代码语言:javascript复制
module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [{
            test: /(.jsx|.js)$/,
            use: {
                loader: "babel-loader",
            },
            exclude: /node_modules/
        }]
    }
}

.babelrc

代码语言:javascript复制
{
  "presets": ["react", "env"]
}

plugins

插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。

Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。

Webpack有很多内置插件,同时也有很多第三方插件,可以让我们完成更加丰富的功能。

现在我们就用内置插件做个小东西

修改webpack.config.js配置文件

代码语言:javascript复制
const webpack = require('webpack'); //引入内置插件
module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/public",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./public",
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [{
                    test: /(.jsx|.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究')
    ],
}

重新打包

代码语言:javascript复制
$ npm start

> webpack-project@1.0.0 start D:wampwwwwebpack
> webpack

Hash: 1f027912d9db7df7db0e
Version: webpack 4.29.3
Time: 1397ms
Built at: 2019-02-14 10:20:36
    Asset      Size  Chunks             Chunk Names
bundle.js  2.16 MiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/greet.json] 58 bytes {main} [built]
[./app/greeter.js] 5.39 KiB {main} [built]
[./app/main.js] 1.23 KiB {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
      11 hidden modules

查看bundle.js文件

HtmlWebpackPlugin

这个插件的作用是依据一个简单的index.html模板,生成一个自动引用你打包后的JS文件的新index.html。这在每次生成的js文件名称不同时非常有用(比如添加了hash值)。

安装

代码语言:javascript复制
$ cnpm install --save-dev html-webpack-plugin
√ Installed 1 packages
√ Linked 55 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-07): 1 packages (detail see file D:wampwwwwebpacknode_modules.recently_updates.txt)
√ All packages installed (54 packages installed from npm registry, used 4s(network 4s), speed 38.09kB/s, json 56(166.11kB), tarball 0B)

1.移除public文件夹,在根目录下创建build文件夹,利用此插件,index.html文件会自动生成,此外CSS已经通过前面的操作打包到JS中了。

2.在app目录下,创建一个index.tmpl.html文件模板,这个模板包含title等必须元素,在编译过程中,插件会依据此模板生成最终的html页面,会自动添加所依赖的 css, js,favicon等文件,index.tmpl.html中的模板源代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Webpack Sample Project</title>
  </head>
  <body>
    <div id='root'>
    </div>
  </body>
</html>

更新webpack.config.js配置文件

代码语言:javascript复制
const webpack = require('webpack'); //引入内置插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'development',
    devtool: 'eval-source-map',
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/build",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./build",//本地服务器所加载的页面所在的目录
        historyApiFallback: true,//不跳转
        inline: true//实时刷新
    },
    module: {
        rules: [{
                    test: /(.jsx|.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'),
        new HtmlWebpackPlugin({
            template: __dirname   "/app/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数
        })
    ],
}

重新打包,重新编译

代码语言:javascript复制
$ npm start

> webpack-project@1.0.0 start D:wampwwwwebpack
> webpack

Hash: b3fdcd46964738ddb0a3
Version: webpack 4.29.3
Time: 2052ms
Built at: 2019-02-14 10:37:47
     Asset       Size  Chunks             Chunk Names
 bundle.js   2.16 MiB    main  [emitted]  main
index.html  417 bytes          [emitted]
Entrypoint main = bundle.js
[./app/greet.json] 58 bytes {main} [built]
[./app/greeter.js] 5.39 KiB {main} [built]
[./app/main.js] 1.23 KiB {main} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
      11 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [./node_modules/_html-webpack-plugin@3.2.0@html-webpack-plugin/lib/loader.js!./app/index.tmpl.html] 615 bytes {0} [built]
    [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
    [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
          1 hidden module
代码语言:javascript复制
$ npm run server

build文件夹中多出两个文件,页面显示正常

产品阶段的构建

目前为止,我们已经使用webpack构建了一个完整的开发环境。但是在产品阶段,可能还需要对打包的文件进行额外的处理,比如说优化,压缩,缓存以及分离CSS和JS。

对于复杂的项目来说,需要复杂的配置,这时候分解配置文件为多个小的文件可以使得事情井井有条,以上面的例子来说,我们创建一个webpack.production.config.js的文件,在里面加上基本的配置,它和原始的webpack.config.js很像,如下

代码语言:javascript复制
onst webpack = require('webpack'); //引入内置插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'production', //模式修改了
    devtool: 'null',//修改为null压缩打包代码
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/build",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./build",//本地服务器所加载的页面所在的目录
        historyApiFallback: true,//不跳转
        inline: true//实时刷新
    },
    module: {
        rules: [{
                    test: /(.jsx|.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'),
        new HtmlWebpackPlugin({
            template: __dirname   "/app/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数
        })
    ],
}

package.json

代码语言:javascript复制
{
  "name": "webpack-project",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "dependencies": {
    "react": "^16.8.1",
    "react-dom": "^16.8.1",
    "webpack": "^4.29.3",
    "webpack-cli": "^3.2.3"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "html-webpack-plugin": "^3.2.0",
    "webpack-dev-server": "^3.1.14"
  },
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "start": "node_modules/.bin/webpack",
    "server": "webpack-dev-server --open",
    "build": "set NODE_ENV=production && webpack --config ./webpack.production.config.js --progress" //windows
  },
  "author": "",
  "license": "ISC"
}
优化插件

webpack提供了一些在发布阶段非常有用的优化插件,它们大多来自于webpack社区,可以通过npm安装,通过以下插件可以完成产品发布阶段所需的功能

  • OccurenceOrderPlugin :为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
  • UglifyJsPlugin:压缩JS代码; //此插件已经不能使用
  • ExtractTextPlugin:分离CSS和JS文件 //extract-text-webpack-plugin目前版本不支持webpack4

我们继续用例子来看看如何添加它们,OccurenceOrder 和 UglifyJS plugins 都是内置插件,你需要做的只是安装其它非内置插件

安装

代码语言:javascript复制
$ cnpm install extract-text-webpack-plugin@next
√ Installed 1 packages
√ Linked 12 latest versions
√ Run 0 scripts
Recently updated (since 2019-02-07): 2 packages (detail see file D:wampwwwwebpacknode_modules.recently_updates.txt)
√ All packages installed (5 packages installed from npm registry, used 2s(network 2s), speed 62.08kB/s, json 13(97.33kB), tarball 12.91kB)

修改webpack.production.config.js

代码语言:javascript复制
/*
* @Author: wyy
* @Date:   2019-02-14 10:45:50
* @Email:  2752154874@qq.com
* @Last Modified by:   wyy
* @Last Modified time: 2019-02-14 10:49:01
*/
const webpack = require('webpack'); //引入内置插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
    mode: 'production',
    devtool: 'null',//修改为null压缩打包代码
    entry: __dirname   "/app/main.js",
    output: {
        path: __dirname   "/build",
        filename: "bundle.js"
    },
    devServer: {
        contentBase: "./build",//本地服务器所加载的页面所在的目录
        historyApiFallback: true,//不跳转
        inline: true//实时刷新
    },
    module: {
        rules: [{
                    test: /(.jsx|.js)$/,
                    use: {
                        loader: "babel-loader",
                    },
                    exclude: /node_modules/
                }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'),
        new HtmlWebpackPlugin({
            template: __dirname   "/app/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数
        }),
        new webpack.optimize.OccurrenceOrderPlugin(),
        new ExtractTextPlugin("style.css")
    ],
}

进行编译

代码语言:javascript复制
$ npm run build

> webpack-project@1.0.0 build D:wampwwwwebpack
> set NODE_ENV=production && webpack --config ./webpack.production.config.js --progress

Hash: c9e8a924b38580a073b8
Version: webpack 4.29.3
Time: 3371ms
Built at: 2019-02-14 11:26:04
     Asset       Size  Chunks             Chunk Names
 bundle.js    117 KiB       0  [emitted]  main
index.html  417 bytes          [emitted]
Entrypoint main = bundle.js
 [2] ./app/main.js 1.23 KiB {0} [built]
 [8] (webpack)/buildin/global.js 472 bytes {0} [built]
 [9] ./app/greeter.js 5.39 KiB {0} [built]
[10] ./app/greet.json 58 bytes {0} [built]
      7 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [0] ./node_modules/_html-webpack-plugin@3.2.0@html-webpack-plugin/lib/loader.js!./app/index.tmpl.html 615 bytes {0} [built]
    [2] (webpack)/buildin/global.js 472 bytes {0} [built]
    [3] (webpack)/buildin/module.js 497 bytes {0} [built]
          1 hidden module

最后附上本文的demo

https://github.com/wangyang0210/bky/tree/webpack

0 人点赞