使用Node.js的Webpack简介

123 阅读4分钟

在靠近用户的地方部署容器

本工程教育(EngEd)计划由科支持。

在全球范围内即时部署容器。Section是经济实惠、简单而强大的。

免费开始

使用Node.js的Webpack简介

2020年8月7日

Webpack是一个用于JavaScript应用程序的静态模块捆绑器。它接收模块,无论是我们创建的自定义文件还是通过NPM安装的东西,并将这些模块转换为静态资产。

这使你能够将一个完全动态的应用程序打包成静态文件,然后你可以将其上传并部署到你的服务器。我们还可以通过插件加载器来扩展webpack的功能。模块是具有离散功能块的JavaScript代码,它将功能抽象化并委托给库,这样我们就不必了解它的复杂性。

为什么使用模块捆绑器和Webpack?

当我们在网页上有很少的JS脚本时,有两种方法来加载JavaScript。

<html>
  <body>
    <script src="index.js"></script>
  </body>
</html>

<html>
  <body>
    <script>
      var foo = "bar";
      console.log(foo);
    </script>
  </body>
</html>

这种方法不能扩展,当我们有很多脚本时,由于网络瓶颈,加载这些脚本就成了问题。如果我们把它们都放在一个文件里,那么就会变得不可维护,并导致变量的名称和范围的问题。

后来出现了**IIFE**,它解决了大型项目的范围问题,但即使改变一个文件也意味着重建整个项目。

JavaScript模块(Node.js模块)

当JavaScript被Node.js买到服务器端的时候,没有HTML文件来添加<script> 标签。CommonJS(一个组织)出现了,并引入了Common.js模块和require ,它允许你在当前文件中加载和使用一个模块。

//math.js
module.exports = function add(a,b){
  return a+b;
}
//index.js
var add = require("./add")

虽然这对Node.js项目来说很好,但没有浏览器对CommonJS的支持。像RequireJSBrowserify这样的捆绑工具就是为此而生的。

ECMAScript模块(ESM)

ECMAScript模块是官方的标准格式,用于打包JavaScript代码以便重复使用。模块是用各种importexport 语句来定义的。

//add.mjs
function add(a,b){
  return a+b;
}
//app.mjs
import {add} from "./add.mjs"
console.log(add(1,2));
// .mjs file extension used for using ES modules in Node

这对网络项目来说是个好消息。然而,浏览器的支持并不完整,而且捆绑的速度仍然比早期的模块实现快。

那么,为什么是Webpack?

Webpack提供了很好的开发者体验,因为它不仅可以捆绑JavaScript应用程序(同时支持EcmaScript Modules和CommonJS),而且当与插件和加载器配对时,它可以用于照顾依赖性和资产,如图像、字体、SASS、CSS等。Webpack会浏览你的项目,并根据导入和导出的内容建立一个依赖关系图

Webpack的入门

Webpack提供了一个命令行界面(CLI),我们可以从终端调用webpack filename.js target/index.js ;以及Node.jsAPI,我们可以在Node.js应用程序中使用。有了webpack 4,我们不需要任何配置就可以使用它。

让我们创建一个虚拟的Node.js项目,并将其与webpack捆绑。你可以使用你的项目。

安装webpack

你需要在你的机器上安装NPMNode

mkdir dummy-project
cd dummy-project
npm init -y
npm install webpack webpack-cli --save-dev

没有配置的webpack

创建以下目录结构。

  webpack-demo
  |- package.json
  |- index.html
  |- /src
  |- index.js

将以下代码添加到index.js

function component() {
  const element = document.createElement('div');
  element.innerHTML = _.join(['Hello', 'world'], ' ');
  return element;
}

document.body.appendChild(component());

index.html

<!doctype html>
<html>
  <head>
    <title>Basic Application</title>
    <script src="https://unpkg.com/lodash@4.16.6"></script>
  </head>
  <body>
    <script src="./src/index.js"></script>
  </body>
</html>

上面的代码之所以有效,是因为我们添加了一个<script> 加载lodash。如果我们运行 **npx webpack**在dummy-project目录下,webpack会在dist 目录下创建一个文件名为main.js 的捆绑包。

src 是 "源代码 "目录,我们在这里编写和编辑我们的代码。 文件夹包含 "分发 "代码,它是构建过程中最小化和优化的输出,最终将被加载到浏览器中。dist

如果我们检查dist/main.js

!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=0)}([function(e,n){document.body.appendChild(function(){const e=document.createElement("div");return e.innerHTML=_.join(["Hello","world"]," "),e}())}]);

让我们在本地安装lodash ,并删除index.html中的<script> 标签。我们还应该调整目录结构,将index.html移到dist ,以使用main.js文件。

npm install --save lodash
src/index.js
  import _ from 'lodash';
  function component() {
  const element = document.createElement('div');
  element.innerHTML = _.join(['Hello', 'world'], ' ');
  return element;
  }

  document.body.appendChild(component());
dist/index.html
  <!doctype html>
  <html>
    <head>
      <title>Basic Application</title>
    </head>
    <body>
      <script src="main.js"></script>
    </body>
  </html>

如果我们现在在浏览器中打开index.html ,会看到 "Hello world"。

使用webpack的配置

Webpack不需要任何配置,但大多数项目需要更复杂的设置,这就是为什么webpack支持配置文件。在dummy-project 目录中添加一个名字为webpack.config.js 的文件。

例子webpack.config.js

const path = require('path');

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

以下是webpack的一些可配置的概念。

  • 入口(Entry)。Entry定义了应用程序的入口点。它是webpack将处理的第一个模块,以建立其依赖关系图。
module.exports = {
  entry: './path/to/my/entry/file.js'
};
  • 输出。输出属性告诉webpack在哪里存储它所创建的捆绑文件以及如何命名这些文件。Javascript文件的默认位置是./dist/main.js ,同时也将其他生成的文件存储在./dist
module.exports = {
  output: {
  filename: 'my-first-bundle.js',
  pathname: __dirname + '/dist'
  }
}
  • 装载器。开箱后,webpack只理解JavaScript和JSON文件。装载器允许webpack处理其他类型的文件,并将其转换为有效的模块,可以被你的应用程序消费并添加到依赖关系图中。
moduel.exports = {
  module: {
  rules: [
  {test: /\.txt$/, use: 'raw-loader'}
  ]
  }
}

test 属性确定了哪个文件应该被转换。use 属性表明应该使用哪个加载器。

  • 插件。虽然加载器被用来转换某些类型的模块,但插件可以被用来执行更广泛的任务,如捆绑优化、资产管理和环境变量的注入。为了使用一个插件,你需要require() ,并将其添加到plugins 阵列中。大多数插件都可以通过选项进行定制。
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  plugins: [
  new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};
  • 模式。模式可以设置为production ,也可以设置为development ,其含义一般。

我们可以在package.json ,将webpack添加到npm脚本中,这样可以简化我们的开发过程。在package.json中添加"build": "webpack", ,并运行命令npm run build

总结

使用webpack的一个巨大优势是它的可定制性和它的热模块重载等功能,我们只讨论了webpack的一些配置方式,请访问这个链接了解更多信息。还有其他一些工具的出现,如Parcel Bundler,但由于webpack的特性,它仍然很适合于大型和复杂的应用程序。请在这里阅读相关的比较。

参考资料

类似文章

[

Building a payroll system with next.js Hero Image

语言, Node.js

用Next.js构建一个薪资系统

阅读更多

](www.section.io/engineering…

Feed-forward and Recurrent Neural Networks Python Implementation Hero Image

语言, Node.js

在React Native中使用React Navigation和嵌套Navigators进行路由选择

阅读更多

](www.section.io/engineering…

Ethers vs web3 Hero Image

区块链, Node.js

Ethers vs. Web3

阅读更多

](www.section.io/engineering…)