心理学之茶哥分享:前端包管理工具整理

1,096 阅读7分钟

大家好,今天由我给大家带来前端心理学茶哥的分享总结。

茶哥是位声音酥酥的小姐姐👧,总结的知识点也是满满的干货,接下来我将对茶哥分享的内容进行整理,以供大家查阅。

首先,前端有很多名词

// 包管理工具
npm
bower
yarn
// 构建
webpack
Grunt
Gulp
require.js
Brunch
parcel
Browserify
Yeoman
Brunch
Broccoli
// 模块定义规范
AMD
CMD
UMD
CommonJS

我们将这些名词分下类,前面几个包管理工具,中间部分是构建类的工具,后面的一部分是模块定义规范。

虽然很久以前前端可能就是单纯的写简单页面的,但现代开发实际情况变得更加复杂。比如游戏开发,时间等等插件都有不同库,因此我们需要包管理工具来管理这些库。

模块定义规范

如何对这些包进行相互间的管理,我们就需要用模块定义规范来进行约束。

在早期的时候我们使用script标签来引入js文件。

<script src="jquery.js"></script>

但是这样会有很大的弊端:在大型项目中我们需要手动来管理引用文件、各个js文件的执行顺序和前后依赖混乱、命名空间可能会冲突等等。久而久之,这样会形成一个非常臃肿的难以维护的代码库。

现在主流的包安装工具npm和其他的包安装工具都有的各自的特点,比如说安装简单,易用易上手等等。

现在的模块规范有commonjscmdamdumd等 ,在webpack中主要是commonjs,但是也支持amd,还对一些不支持模块规范的很老的库支持Polyfill垫片。

我们先简单讲下最常见的模块定义规范。 首先我们讲下commonjscommonjs中一个文件就是一个模块,他主要使用require同步加载模块,最后呢,将要输出的变量或者方法添加单export上面

const someFun= require('./moduleA');//引入
module.export=something //导出

这种方式比较适用于服务器端,所有的模块已经保存在服务器端,因此加载起来比较快。

但是在浏览器中明显很不合适,考虑到会造成同步阻塞,因此有了异步加载模式amd

// 基本语法
define(id,dependences,function(require,exports,module){})
// 创建一个名为"alpha"的模块,使用了require,exports,和名为"beta"的模块:
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
    exports.verb = function() {
       return beta.verb();
       // Or:
       return require("beta").verb();
    }
});

Webpack

webpack是资源模块化管理打包工具,webpack前身有gruntgulpwebpack有两者相同的功能,但是又和他们不同:webpack是模块管理工具,后面两者更类似于任务管理器。

但实际项目中,webpack最重要的是配置好配置文件。

安装webpack

我们接下来讲下webpack的安装

我们可以先安装nodejsnodejs自带软件管理包npm,我们就可以用npm安装webpack(以下操作也可以使用yarn操作,大同小异)。

webpack有两种方式,全局安装和局部安装。

我们建议局部安装,这样webpack有升级也不会影响到我们本地的项目,有兴趣的也可以看看npx命令。

npm i weback -D

在webpack升级到4的时候,我们必须安装webpack-cli否则无法启动webpack

npm i weback-cli -D

运行webpack有几种方式:

  • 第一种是在终端通过命令:webpack + 文件路径+webpack参数来启动,这样比较繁琐。

  • 另一种是通过webpack.config.js配置文件来启动项目。这个文件实际是一个nodejs模块,返回一个json的配置对象。webpack结合配置文件就可以了。

  • 还有一种方式通过npm的package.json文件的scripts属性里面配置

"script":{"open": "webpack --progress --colors --watch"}

然后运行npm run open即可。

基本项目

现在我们新建一个项目

// -y是执行默认行为
npm init -y

项目结构

app/
  entry.js
  sub.js
  index.html
package.json
webpack.config.js

entry.js就是入口文件

var sub = require('./sub.js');
var app  = document.createElement('div');
app.innerHTML = '<h1>Hello World</h1>';
app.appendChild(sub());
document.body.appendChild(app);

sub.js

// 我们在这里使用commonjs的风格
function generatorText(){
  var element=ducumnt.createElement('h2');
  element.innerHTML='Hello h2';
  return element
}
module.exports=generatorText

index.html是html模板,为了展示执行js的效果,我们就简单引入html的模板

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title><%= htmlWebpackPlugin.options.title %></title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" media="screen" href="main.css" />
    <script src="main.js"></script>
  </head>
  <body>
  </body>
</html>

webpack配置

接下来重点讲下webpack.config.js的内容。这个文件主要分为两个部分,第一部分是引入各个模块,第二个部分就是模块导出对象,这个是重点。

var webpack=require('wenpack');
const path = require("path");
module.exports={
  mode:'development',
  entry:'./entry.js',
  output:{
    path:path.resolve(__dirname, 'dist'),,
    filename:'bundle-[hash:8].js'
  },
  module:{},
  plugins: [],
  
}

第一个部分就是commonjs用require引入模块

这里有些是webpack自带的模块,还有一些是node里面的模块。比如path,就是为了避免多端的路径产生问题。

其中第一个是entry属性,这是入口js文件。当代码启动的时候,首先执行的就是入口文件,其他的模块是等到遇到require方法才开始执行的。可以指定一个文件,也可以指定多个文件。

然后是output属性,这个是设置webpack将转换好的模块打包的位置。里面有多个选项配置,path 路径,filename文件名,这里可以使用hash属性来防止浏览器进行缓存。 还可以对多个公共模块进行提取,这个稍后讲。

第三个重点呢就是module ,就是node转换器,用于将其他文件类型,css jsx 图片。因为webpack只能处理js,因此要用转换器来对这些文件类型转换打包

配置的mode是webpack4新增的一条属性,它的意思为当前开发的环境,可以为"development"或者"production"

更多基本的属性可以参阅webpack文档

插件1:html-webpack-plugin

除此之外,我们虽然设置了html模板,我们要引入html-webpack-plugin插件来进行配置才能使用。

安装

npm i html-webpack-plugin -D

配置

// webpack.config.js中增加配置
 ···
 const HtmlWebpackPlugin = require("html-webpack-plugin");
 // 在plugins数组添加
  new HtmlWebpackPlugin({
      title: "My App",
      filename: "index.html",
      template: "./app/index.html",
      hash: true
    }),
 ···

插件2:clean-webpack-plugin

现在我们执行npx webpack就会在dist文件夹生成文件

dist/
    bundle-8cecda3d.js
    bundle-xxxxxxxx.js
    bundle-xxxxxxxx.js
    index.html

生成每次带有hash的文件并不会自动清除,我们可以使用clean-webpack-plugin插件,来清除多余的文件。 安装

npm i clean-webpack-plugin -D

配置

// webpack.config.js中增加配置
···
// 清除dist文件的插件
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
//在plugins数组中添加
new CleanWebpackPlugin(),
···

插件3:webpack-dev-server

webpack自带本地服务器,可以在devServer进行配置。当然我们也可以使用node服务器,或者apache配置。

现在讲一下devServer属性配置

npm i webpack-dev-server -D
// webpack.config.js中增加配置
...
devServer:{
  // 这个属性主要用于SPA,单页面开发时,如果设置为true,所有的跳转将指向index
  historyApiFallback:true,
  // 启用 webpack 的 模块热替换 功能
  hot:true,
  // 处理实时重载的脚本被插入到你的包(bundle)中,并且构建消息将会出现在浏览器控制台
  inline:true,
  // 默认webpack以项目根目录为起始路径,如果你想指定目录可以在这里设置、
  contentBase: path.join(__dirname, 'dist'),
  // 将运行进度输出到控制台
  progress:true// 设置监听端口,默认8080
  port:3002// 自动打开浏览器
  open:true
}
...

先执行npx webpack再执行npx webpack-dev-server,这样,我们就可以在浏览器中看到我们的页面了。

此时,将以上命令联合,可以配置在package.json的scripts中,比如

"scripts": {
    "dev": "npx webpack && npx webpack-dev-server"
  }

额外插件介绍

在实际开发目录中,我们可以使用双服务器模式,可以使用中间件webpack-dev-middleware,但是只能在生产环境使用。他可以在内存中实时打包,生成虚拟文件,供浏览器实时访问以及调试。

这里推荐一个插件,叫做打包面板Webpack-dashboard,使用效果如下图,看起来页面更加简洁。

结语

本来茶哥周四已经分享了的,但是我周末有团建,周天又去参加社区活动,这才延迟了总结时间,真心感到抱歉。

以上就是前端心理学茶哥的分享总结,感谢茶哥的分享🙌。让我们期待茶哥的下一次分享,大家一起学习进步。