20

为什么需要webpack

现在的前端网页非常丰富,特别是SPA技术流行后,js的复杂度增加并且有时需要一大堆的依赖包,还需要解决SCSS Lesscss预处理等的编译工作。所以现在的前端已经相当依赖 webpack 来更好的管理项目了。

现在所流行的vue react angluar 已经和webpack非常的密切了,官方都推出了和自身框架依赖的webpack构架工具。

什么是webpack

webpack 可以看作是一个打包工具,它可以分析你的项目结构,然后找到js 模块以及一些浏览器不能直接执行的一些语言比如 Less 、TypeScript 等,并将其转换和打包为一个合法的格式以供浏览器使用。webpack从3.0之后还担负起了优化项目的功能.

现在的webpack已经到了4.X版本了,我也是全程使用了 webpack ^4.4.1

webpack安装和使用

mkdir webpack_demo
cd webpack_demo
// npm初始化
npm init
// 然后一直回车

安装webpack

// 不建议全局安装
cnpm install webpack --save-dev

// --save是要保存到package.json中,dev是在开发时使用这个包,而生产环境中不使用。

首先来一个小demo吧

目录结构

| dist
    - index.html
| node_modules
| src
    - index.js

完善文件内容

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

  // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return element;
}

document.body.appendChild(component());
// index.html
<!doctype html>
<html>
  <head>
    <title>Getting Started</title>
  </head>
  <body>
    <script src="./bundle.js"></script>
  </body>
</html>
// 执行命令
$ npx webpack src/index.js --output dist/bundle.js

npx: installed 1 in 7.613s
Path must be a string. Received undefined
D:\myweb\webpack\webpack_study_demo\webpack_demo01\node_modules\_webpack@4.4.1@webpack\bin\webpack.js
The CLI moved into a separate package: webpack-cli
Would you like to install webpack-cli? (That will run npm install -D webpack-cli) (yes/NO)NO
It needs to be installed alongside webpack to use the CLI


// 这里提示安装 webpack-cli
// 是因为到了webpack4,  webpack 已经将 webpack 命令行相关的内容都迁移到 webpack-cli,所以除了 webpack 外,我们还需要安装 webpack-cli:
// 安装webpack-cli
cnpm install webpack-cli --save
// 在次执行
npx webpack src/index.js --output dist/bundle.js
npx: installed 1 in 5.327s
Path must be a string. Received undefined
D:\myweb\webpack\webpack_study_demo\webpack_demo01\node_modules\_webpack@4.4.1@webpack\bin\webpack.js
Hash: c0cb86e7079d57cac106
Version: webpack 4.4.1
Time: 4707ms
Built at: 2018-4-2 21:18:48
    Asset      Size  Chunks             Chunk Names
bundle.js  69.9 KiB       0  [emitted]  main
Entrypoint main = bundle.js
   [1] (webpack)/buildin/module.js 519 bytes {0} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] ./src/index.js 266 bytes {0} [built]
    + 1 hidden module

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/

// 有一个警告
// 说'mode'没有定义,这是 webpack  4x 引入的,有两个值,development 和 production。默认是production.

由于webpack 默认的入口文件是从./src/index.js,输出是./dist/main.js 。因此可以直接 npx webpack --mode development

> npx webpack --mode development
npx: installed 1 in 5.759s
Path must be a string. Received undefined
D:\myweb\webpack\webpack_study_demo\webpack_demo01\node_modules\_webpack@4.4.1@webpack\bin\webpack.js
Hash: 36739af911cbe57bdd95
Version: webpack 4.4.1
Time: 1060ms
Built at: 2018-4-2 21:25:02
  Asset     Size  Chunks             Chunk Names
main.js  550 KiB    main  [emitted]  main
Entrypoint main = main.js
[./node_modules/_webpack@4.4.1@webpack/buildin/global.js] (webpack)/buildin/global.js 509 bytes {main} [built]
[./node_modules/_webpack@4.4.1@webpack/buildin/module.js] (webpack)/buildin/module.js 519 bytes {main} [built]
[./src/index.js] 266 bytes {main} [built]
    + 1 hidden module

// 打包完毕了
// 我们可以打开 `dist/index.html` 查看一下.

配置文件

上面的 demo 并没有使用配置文件,而是使用 CLI 来实现打包的,那么我们现在来学习一下配置文件吧。

// webpack.config.js
module.exports = {
    //入口文件的配置项
    entry:{},
    //出口文件的配置项
    output:{},
    //模块:例如解读CSS,图片如何转换,压缩
    module:{},
    //插件,用于生产模版和各项功能
    plugins:[],
    //配置webpack开发服务功能
    devServer:{}
}
入口起点

单文件

module.exports = {
    entry: "./src/index.js"
}

多文件

// 对象语法
module.exports = {
    entry: {
        app: "./sec/app.js",
        vendors: "./src/vendors.js" 
    }
}

// 应用场景: 分离应用程序、和第三方库入口、多页面应用程序

// 多页面应用程序
const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};
出口

基本用法

// webpack.config.js
const path = require('path');
const config = {
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

module.exports = config;

多入口起点

//
{
    entry: {
        app: './src/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name].js',
        path: __dirname + '/dist'
    }
}
// 这里的[name]是占位符,之后会替换为 app、search
// 写入到硬盘:./dist/app.js, ./dist/search.js

继续上面的小demo

// webpack.config.js
var path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
}
// 执行
$ npx webpack --config webpack.config.js
// 同样能打包OK

上面讲的比较零碎呢,看着不爽,那我们再来一个比较实用一点的demo吧

目录结构
| dist
    - index.html
| src
    - index.js
| package.json
| webpack.config.js
具体代码实现
// webpack.config.js
var path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/bundle.js'
  }
}
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="title"></div>
  <script src="./js/bundle.js"></script>
</body>
</html>
// index.js
document.getElementById('title').innerHTML = 'hello webpack';

到了重点所在了哦

// package.json
{
  "name": "webpack_new_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode development"
    // "build": "webpack --config webpack.config.js --mode development"
    // 上面两种配置等价,--config webpack.config.js可以不写,默认是它。
    // webpack 4.0之后多了mode的配置,因此我们需要配置一下,不然会出现警告哦
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.4.1",
    "webpack-cli": "^2.0.13"
  }
}

运行一下

$ npm run build

> webpack_new_test@1.0.0 build D:\myweb\webpack\webpack_study_demo\webpack_new_test
> webpack --mode development

Hash: 8603f6b2e76022d881d9
Version: webpack 4.4.1
Time: 106ms
Built at: 2018-4-3 16:32:55
       Asset      Size  Chunks             Chunk Names
js/bundle.js  2.87 KiB    main  [emitted]  main
Entrypoint main = js/bundle.js
[./src/index.js] 61 bytes {main} [built]
  • 补充
// 按道理我们在本地安装了webpack,这部就是应该直接运行webpack 就可以打包了嘛

>$  webpack
webpack : 无法将“webpack”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路
径正确,然后再试一次。
所在位置 行:1 字符: 1
+ webpack
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (webpack:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

// 恰恰报错了呢


// 解决办法一
全局安装 webpack 和 webpack-cli

// 解决办法二
就是上诉我们在package.json中进行配置
"build": "webpack --mode development" 
未完待续,小编会继续往下写哦~~
参考文献

官方文档
技术胖


Meils
1.6k 声望157 粉丝

前端开发实践者