webpack - wbwangk/wbwangk.github.io GitHub Wiki

环境:ubuntu16.4桌面版 #

安装nodejs、npm#

官方快速开始

原文

mkdir webpack-demo && cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev

npm init会生成package.json--save-dev会向package.jsondevDependencies中写入依赖。node_modules目录下是安装后的webpack、webpack-cli及其依赖的组件。

原文首先给出一个index.html的例子,在里面引用lodash.js。然后说这样不好,因为这个依赖包含在代码中,没有被管理。

安装lodash:

npm install --save lodash

--save选项使依赖保存在package.json的dependencies中,即lodash会打包到运行时。而devDependencies表示仅在开发过程中依赖(运行时不依赖)。

修改src/index.js(加号表示增加行,减号表示删除这行):

+ import _ from 'lodash';
+
  function component() {
    var element = document.createElement('div');

-   // Lodash, currently included via a script, is required for this line to work
+   // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');

    return element;
  }

  document.body.appendChild(component());

import并不是传统的javascript的语法(它是ECMAScript 2015的标准)。它会被webpack构建后放入dist目录下的bundle.js文件中。

修改dist/index.html:

  <!doctype html>
  <html>
   <head>
     <title>Getting Started</title>
-    <script src="https://unpkg.com/[email protected]"></script>
   </head>
   <body>
-    <script src="./src/index.js"></script>
+    <script src="dist/bundle.js"></script>
   </body>
  </html>

看样子webpack把index.js和index.js依赖的lodash打包到了boudle.js中。

执行构建

可以执行npx webpack./node_modules/.bin/webpack。如果全局安装webpack,甚至可以直接执行webpack

实测发现webpack构建生成的输出文件不是bundle.js,而是main.js。所以dist/index.html应该是:

-    <script src="dist/bundle.js"></script>
+    <script src="main.js"></script>

由于测试使用的是桌面版ubuntu,所以可以直接用图形界面中的火狐浏览器打开dist/index.html,也可以显示'Hello webpack'。

Modules

importexportES2015标准语法,但不被主流浏览器支持,通过webpack可以把它们编译成浏览器支持的语法。

除了importexport,webpack并不会转译其他的ES2015语法,如果你想使用这种语法,需要你自己引入一个转译器,如Babel(parity教程使用的这个)。引入转译器需要用到webpack的loader系统。

使用配置

webpack使用配置文件来控制其行为。它的配置文件叫webpack.config.js,位于项目的根目录下。

编辑webpack.config.js:

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

看到这里就明白为啥webpack生成的js文件不叫builde.js而是main.js,因为没有创建这个配置文件。

使用新创建的配置文件重新执行webpack构建:

npx webpack --config webpack.config.js

会发现dist目录下有了两个几乎一样的js文件:main.js和bundle.js,main.js是上次未指定配置文件时构建的。

其实webpack默认就会加载webpack.config.js,这里放在命令行参数中是为了解释而已。

NPM Scripts

命令webpack(或npx webpack)会触发webpack的构建。如果把这个命令放入package.json的scripts,如:

  {
    "name": "webpack-demo",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
+     "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "webpack": "^4.0.1",
      "webpack-cli": "^2.0.9",
      "lodash": "^4.17.5"
    }
  }

则当执行npm run build的时候,会自动触发webpack的构建执行。注意,在scripts中指定的包,就像用npx执行它一样的效果。

另一篇入门

中文原文

里面的这段话把webpack的功能描述的比较到位:

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

解释一下entry和output

$ webpack --help
Usage without config file: webpack <entry> [<entry>] --output [-o] <output>
...

例如,本地安装的webpack(非全局安装)可以这样执行:

$ node_modules/.bin/webpack app/main.js public/bundle.js

上面第一个参数是entry,第二个就是输出了。

假如main.js是:

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

而Greeter.js是:

module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "Hi there and greetings!";
  return greet;
};

则执行上面的webpack命令后就输出了bundle.js,将两个输入js文件的内容合并到了bundle.js中。

通过配置文件

如果把上面的命令行方式变成配置文件的方式,需要定义一个配置文件webpack.config.js:

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

entry和output都在上面的配置文件中了。

注:“__dirname”是node.js中的一个全局变量,它指向webpack.config.js所在的目录。

webpack-dev-server

webpack自带了一个web服务器,默认通过8080端口提供网页服务。

安装:

npm install --save-dev webpack-dev-server

执行可以通过npx webpack-dev-servernode_modules/.bin/webpack-dev-server。也可以放入到package.json中:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack",
    "server": "webpack-dev-server --open"
  },

然后通过npm run server来启动上面配置的命令。

loaders

Loaders是webpack提供的最激动人心的功能之一了。

通过使用不同的loader,webpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理,比如说分析转换scss为css,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件,对React的开发而言,合适的Loaders可以把React的中用到的JSX文件转换为JS文件。

Loaders在webpack.config.js中的module.rules关键字下进行配置。其配置包括以下几方面:

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

  • loader:loader的名称(必须)

  • include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);

  • query:为loaders提供额外的设置选项(可选)

Babel

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

  • 让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器完全支持;

  • 让你能使用基于JavaScript进行了拓展的语言,比如React的JSX;

在webpack中配置Babel的方法如下:

module.exports = {
    entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"//打包后输出文件的文件名
    },
    devtool: 'eval-source-map',
    devServer: {
        contentBase: "./public",//本地服务器所加载的页面所在的目录
        historyApiFallback: true,//不跳转
        inline: true//实时刷新
    },
    module: {
        rules: [
            {
                test: /(\.jsx|\.js)$/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: [
                            "env", "react"
                        ]
                    }
                },
                exclude: /node_modules/
            }
        ]
    }
};

http-server

webpack@4似乎引入了一个新的web服务器,安装:

$ npm install --savedev http-server

然后配置package.json:

{
  ...
  "scripts": {
-    "build": "webpack"
+    "build": "webpack",
+    "start": "http-server dist"
  },
  ...
}

启动http-server(或执行npx http-server dist):

$ npm start
Starting up http-server, serving dist
Available on:
  http://127.0.0.1:8080
  http://10.0.2.15:8080
  http://192.168.16.107:8080
...

dist目录(相对于package.json所在的目录)就是web服务器的根目录。

⚠️ **GitHub.com Fallback** ⚠️