• webpack——快速入门【一】


    学习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/#%E5%85%A5%E5%8F%A3-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平台,安装都只是安装到项目文件夹中没有进行全局安装

    创建空文件夹

    $ 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指向淘宝镜像

    $ 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.KINGDesktopwebpack
    ode_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

    $ cd app
    
    $ vi greeter.js
    
    $ vi main.js
    

    greeter.js

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

    module.exports = function() {
      var greet = document.createElement('div');
      greet.textContent = "小哥哥,快来啊,快活啊";
      return greet;
    };

    main.js

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

    const greeter = require('./Greeter.js');
    document.querySelector("#root").appendChild(greeter());

    cd到public下面创建index.html

    $ cd ..
    
    $ cd public/
    $ vi index.html

    index.html

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

    <!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>

    打包

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

    $ 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文件,主要配置入口文件和打包后文件

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

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

    修改greeter.js

    就是改了下文字内容~

    module.exports = function() {
      var greet = document.createElement('div');
      greet.textContent = "We still hava a long way to go.";
      return greet;
    };

    重新打包

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

    $ 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初始化一个就可以了,现在开始配置。

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

    $ npm init

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

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

    "start":"node_modules/.bin/webpack"  

    完整的json文件如下

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

    module.exports = function() {
      var greet = document.createElement('div');
      greet.textContent = "Hello world";
      return greet;
    };

    使用自定义的命令打包

    $ 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,进行如下配置:

    module.exports = {
        devtool: 'eval-source-map',
        entry: __dirname + "/app/main.js",
        output: {
            path: __dirname + "/public",
            filename: "bundle.js"
        }
    }

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

    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中配置模式造成了,我们顺手也配置下吧

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

    构建本地服务器

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

    $ 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:wampwwwwebpack
    ode_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

    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对象中添加如下命令,用以开启本地服务器:

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

    运行服务

    $ 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

    {
      "greetText": "Hi there and greetings from JSON!"
    }

    greeter.js

    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的,不然是会报错的,报错不可怕,只要看信息总会解决的!

    $ 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:wampwwwwebpack ode_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文件

    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......

    $ 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:wampwwwwebpack
    ode_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组件

    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模块

    import React from 'react';
    import {render} from 'react-dom';
    import Greeter from './greeter';
    
    render(<Greeter />, document.getElementById('root'));

    然后重新打包

    $ 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

    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

    {
      "presets": ["react", "env"]
    }

    plugins

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

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

    现在我们就用内置插件做个小东西
     
    修改webpack.config.js配置文件
    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('版权所有,翻版必究')
        ],
    }

    重新打包

    $ 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值)。
     
    安装
    $ 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:wampwwwwebpack
    ode_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中的模板源代码如下:

    <!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配置文件

    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 一个这个插件的实例,并传入相关的参数
            })
        ],
    }

    重新打包,重新编译

    $ 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
    $ npm run server

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

    产品阶段的构建

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

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

    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

    {
      "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 都是内置插件,你需要做的只是安装其它非内置插件

     安装

    $ 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:wampwwwwebpack ode_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

    /*
    * @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")
        ],
    }

     进行编译

    $ 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

  • 相关阅读:
    MFC中char*,string和CString之间的转换
    图像分割之(四)OpenCV的GrabCut函数使用和源码解读
    自然图像抠图/视频抠像技术发展情况梳理
    OpenCV混合高斯模型函数注释说明
    Effective STL 为包含指针的关联容器指定比较类型
    vs2010修改状态栏的CStatusBar指针的的SetPaneText()方法时死活不对问题
    windows c/c++ 代码运行时间,毫秒级
    【Math】根据置信度、样本数相关推导过程
    宝宝加减法出题小程序
    混淆矩阵
  • 原文地址:https://www.cnblogs.com/wangyang0210/p/10371064.html
Copyright © 2020-2023  润新知