webpack

2019-05-01 作者:计算机教程   |   浏览(159)

WebAssembly 支持

Webpack 现在默认支持在任何本地 WebAssembly 模块中的 importexport 语句。这意味着你可以直接在 Rust, C , C 或者其它 WebAssembly 支持语言中使用 import

为什要使用WebPack

现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法

  • 模块化,让我们可以把复杂的程序细化为小的文件;
  • 类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能能装换为JavaScript文件使浏览器可以识别;
  • Scss,less等CSS预处理器
  • ...

这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常反锁的,这就为WebPack类的工具的出现提供了需求。

webpack 4 更快(速度提升98%)!

我们在社区中请求大家对 webpack 4 进行构建性能测试,得出的结果非常有趣。结果很惊人,构建时间降低了 60%-98%!!这里给大家分享一下某个用户的测试结果:

图片 1

图片 2

来源: Twitter

当然这只是一部分用户的测试数据,你可以在我的推文的回复中查看他们所有的结果。

性能测试过程中也发现了一些 loader 的 bug 我们已经及时修复了!!PS: 我们还没有实现多进程,或者缓存功能(计划在v5版实现)。所以理论上我们的性能还有非常大的提升空间!!!!

构件速度是我们此次发布最主要的目标。你可以把所有的功能都添加到工具中,但是如果不能节省开发时间那你加这些功能又有什么用呢?当然以上的这些都是部分示例,我们非常欢迎大家在推特上使用 #webpack #webpack4 开头提交你们的构建时间报告。

Babel

Babel其实是一个编译JavaScript的平台,它的强大之处表现在可以通过编译帮你达到以下目的:

  • 下一代的JavaScript标准(ES6,ES7),这些标准目前并未被当前的浏览器完全的支持;
  • 使用基于JavaScript进行了拓展的语言,比如React的JSX

接下来?

我们已经在着手计划下一个版本 webpack 4.x 和 5 的特性了,包括但不限于:

  • ESM 模块导出支持
  • 持久缓存
  • WebAssembly 支持从 experimental 升级为 stable 稳定版。并增加 tree-shaking 和未使用代码去除!
  • Presets —— 基于零配置设计,任何东西都能支持零配置
  • CSS 模块类型——支持 CSS 作为入口文件(再见吧 ExtractTextWebpackPlugin)
  • HTML 模块类型——支持 HTML 作为入口文件
  • URL/文件 模块类型
  • 自定义模块类型
  • 多线程
  • 重新定义我们的组织章程和计划任务
  • Google Summer of Code (之后单独写文说明!!!)

使用插件的方法

要使用某个插件,我们需要通过npm安装它,然后要做的就是在webpack配置中的plugins关键字部分添加该插件的一个实例(plugins是一个数组)继续看例子,我们添加了一个实现版权声明的插件。

//webpack.config.js
var webpack = require('webpack');

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

  module: {
    loaders: [
      { test: /.json$/, loader: "json" },
      { test: /.js$/, exclude: /node_modules/, loader: 'babel' },
      { test: /.css$/, loader: 'style!css?modules!postcss' }//这里添加PostCSS
    ]
  },
  postcss: [
    require('autoprefixer')
  ],

  plugins: [
    new webpack.BannerPlugin("Copyright Flying Unicorns inc.")//在这个数组中new一个就可以了
  ],

  devServer: {...}
}

通过这个插件,打包后的JS文件显示如下

图片 3

bundled JavaScript file

知道Webpack中的插件如何使用了,下面给大家推荐几个常用的插件

v4 的文档在哪?

我们马上要完成迁移指南和v4 的文档了。你可以访问 文档仓库 切换到 next 分支来获取更新情况,当然能搭把手帮个忙是再好不过了!

更快捷的执行打包任务

执行类似于node_modules/.bin/webpack这样的命令其实是比较烦人且容易出错的,不过值得庆幸的是npm可以引导任务执行,对其进行配置后可以使用简单的npm start命令来代替这些繁琐的命令。在package.json中对npm的脚本部分进行相关设置即可,设置方法如下。

{
  "name": "webpack-sample-project",
  "version": "1.0.0",
  "description": "Sample webpack project",
  "scripts": {
    "start": "webpack" //配置的地方就是这里啦,相当于把npm的start命令指向webpack命令
  },
  "author": "zhang",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^1.12.9"
  }
}

注:package.json中的脚本部分已经默认在命令前添加了node_modules/.bin路径,所以无论是全局还是局部安装的Webpack,你都不需要写前面那指明详细的路径了。

npm的start是一个特殊的脚本名称,它的特殊性表现在,在命令行中使用npm start就可以执行相关命令,如果对应的此脚本名称不是start,想要在命令行中运行时,需要这样用npm run {script name}npm run build,以下是执行npm start后命令行的输出显示

图片 4

npmStartTermialResult

现在只需要使用npm start就可以打包文件了,有没有觉得webpack也不过如此嘛,不过不要太小瞧Webpack,其强大的功能包含在其一系列可供配置的选项中,我们一项项来看。

️‍ 有什么更新?

webpack 4 有太多的新东西可以说了,但是我不可能在本文中列举所有的内容,否则这篇文章就要推迟很久才能发布了。因此下面我会和大家分享一些我觉得有趣的更新内容,如果大家想要看所有的更新的话可以查阅 webpack 4 的更新日志

安装

Webpack可以使用npm安装,新建一个空的练习文件夹(此处命名为webpack sample progect),在终端中转到该文件夹后执行下述指令就可以完成安装。

//全局安装
npm install -g webpack
//安装到你的项目目录
npm install --save-dev webpack

为什么叫 Legato?

首先我们会开始一个新传统:为我们以后的每个大版本设定代号!因此,我们决定将命名这个特权给予我们最大的 OpenCollective 捐赠者:trivago

当我们向其发出请求后他们是这么回复我们的:

[在 trivago] 我们通常以音乐主题来命名我们的项目。例如,我们之前的 JS 框架叫 “Harmony”,我们的新框架叫“Melody”。PHP 的话我们使用基于 Symfony 上层封装,我们叫它“Orchestra”。 Legato 意味着毫无间隙地连续演奏每个节奏。 这点和 Webpack 很像,Webpack 将我们的前端资源(JS,CSS甚至更多)无间隙的打包在一起。因此我们相信 “Legato” 这个代号会适合 Webpack。 ——  Patrick Gotthardt

我们得知后也非常地激动,因为新版 Webpack 中我们所做的每一个更新目的都在于此,为了当大家在使用 Webpack 的时候敏捷连续毫无顿挫感。非常感谢过去的这些年 trivago 对 webpack 的无私捐赠支持,更感谢其为 webpack 4 命名!

引申阅读:trivago 帮助保护 webpack 的未来

Babel的配置选项

Babel其实可以完全在webpack.config.js中进行配置,但是考虑到babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。我们现在的babel的配置并不算复杂,不过之后我们会再加一些东西,因此现在我们就提取出相关部分,分两个配置文件进行配置(webpack会自动调用.babelrc里的babel配置选项),如下:

// webpack.config.js
module.exports = {
  devtool: 'eval-source-map',

  entry:  __dirname   "/app/main.js",
  output: {
    path: __dirname   "/public",
    filename: "bundle.js"
  },

  module: {
    loaders: [
      {
        test: /.json$/,
        loader: "json"
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      }
    ]
  },

  devServer: {...} // Omitted for brevity
}
//.babelrc
{
  "presets": ["react", "es2015"]
}

到目前为止,我们已经知道了,对于模块,Webpack能提供非常强大的处理功能,那那些是模块呢。

模块类型简介以及 .mjs 支持

之前,JS 一直都是 Webpack 唯一的一等模块类型。当用户不需要使用 CSS/HTML 的时可能会造成一些麻烦。我们基于新的 API 抽象实现了 JS 类型。目前,我们已经支持5种模块类型实现:

  • javascript/auto: _(webpack 3 默认值)_ 所有的 JS 模块规范都可用:CommonJS,AMD,ESM
  • javascript/esm:EcmaScript 模块规范,其它的模块规范都不可用 (.mjs 文件的默认值)
  • javascript/dynamic: 仅支持 CommonJS 和 AMD,EcmaScript 模块规范不可用
  • json: JSON 数据,使用 requireimport 导入 JSON 数据时可用 (.json 文件的默认值)
  • webassembly/experimental: WebAssembly 模块 (.wasm 文件的默认值,目前还是试验阶段)
  • 另外 webpack 支持直接查找 .wasm, .mjs, .js.json 后缀文件

最让人激动的是,我们甚至可以支持 CSS 和 HTML 模块类型(计划在 webpack 4.x – 5 间版本实现)。 它将允许我们直接将 HTML 作为入口文件!

Webpack的强大功能

再次感谢

对于我们的贡献者团队,核心团队,loader 和插件作者,那些第一次提交他们的提交,或者帮助解决故障的人:我们不能不感谢你们。这个产品是为你而生的,你们帮助塑造了它

2018 我们将注定要抛弃老古董思维,迎接 JS 的美丽复兴!❤

我之前已经多次强调过,在 JS 复兴 的今天,没有社区的帮忙,webpack 是不会变的如此强大,可持续以及蓬勃的生长。如果没有你们的帮助,webpack 可能现在也还只是另外一款普通的构建工具[Yet Another Build Tool (YABT)]而已。

via: https://medium.com/webpack/webpack-4-released-today-6cdb994702d4

1 赞 收藏 评论

图片 5

什么是Webpack

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

为什么你用如此多的 emoji 表情?

因为这样写文章很开心呀!大家也可以试试 。

CSS预处理器

Sass 和 Less之类的预处理器是对原生CSS的拓展,它们允许你使用类似于variables, nesting, mixins, inheritance等不存在于CSS中的特性来写CSS,CSS预处理器可以这些特殊类型的语句转化为浏览器可识别的CSS语句,
你现在可能都已经熟悉了,在webpack里使用相关loaders进行配置就可以使用了,以下是常用的CSS 处理loaders

  • Less Loader
  • Sass Loader
  • Stylus Loader

不过其实也存在一个CSS的处理平台-PostCSS,它可以帮助你的CSS实现更多的功能,在其CSS官方文档可了解更多相关知识。

举例来说如何使用PostCSS,我们使用PostCSS来为CSS代码自动添加适应不同浏览器的CSS前缀。

首先安装postcss-loader 和 autoprefixer(自动添加前缀的插件)

npm install --save-dev postcss-loader autoprefixer

接下来,在webpack配置文件中进行设置,只需要新建一个postcss关键字,并在里面申明依赖的插件,如下,现在你写的css会自动根据Can i use里的数据添加不同前缀了。

//webpack配置文件
module.exports = {
  devtool: 'eval-source-map',
  entry: __dirname   "/app/main.js",
  output: {...},

  module: {
    loaders: [
      {
        test: /.json$/,
        loader: "json"
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      },
      {
        test: /.css$/,
        loader: 'style!css?modules!postcss'
      }
    ]
  },

  postcss: [
    require('autoprefixer')//调用autoprefixer插件
  ],

  devServer: {...}
}

到现在,本文已经涉及到处理JS的Babel和处理CSS的PostCSS,它们其实也是两个单独的平台,配合Webpack可以很好的发挥它们的作用。接下来介绍Webpack中另一个非常重要的功能-Plugins

还有!

还有更多的特性没有在本文列出,我们强烈建议大家去看一下我们的官方更新日志

CSS

webpack提供两个工具处理样式表,css-loader 和 style-loader,二者处理的任务不同,css-loader使你能够使用类似@import 和 url(...)的方法实现 require()的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。

继续上面的例子

//安装
npm install --save-dev style-loader css-loader
//使用
module.exports = {
  devtool: 'eval-source-map',

  entry:  __dirname   "/app/main.js",
  output: {
    path: __dirname   "/build",
    filename: "bundle.js"
  },

  module: {
    loaders: [
      {
        test: /.json$/,
        loader: "json"
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      },
      {
        test: /.css$/,
        loader: 'style!css'//添加对样式表的处理
      }
    ]
  },

  devServer: {...}
}

:感叹号的作用在于使同一文件能够使用不同类型的loader

接下来,在app文件夹里创建一个名字为"main.css"的文件,对一些元素设置样式

html {
  box-sizing: border-box;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
}

*, *:before, *:after {
  box-sizing: inherit;
}

body {
  margin: 0;
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1, h2, h3, h4, h5, h6, p, ul {
  margin: 0;
  padding: 0;
}

你还记得吗?webpack只有单一的入口,其它的模块需要通过 import, require, url等导入相关位置,为了让webpack能找到”main.css“文件,我们把它导入”main.js “中,如下

//main.js
import React from 'react';
import {render} from 'react-dom';
import Greeter from './Greeter';

import './main.css';//使用require导入css文件

render(<Greeter />, document.getElementById('root'));

通常情况下,css会和js打包到同一个文件中,并不会打包为一个单独的css文件,不过通过合适的配置webpack也可以把css打包为单独的文件的。
不过这也只是webpack把css当做模块而已,咱们继续看看一个真的CSS模块的实践。

Mode, 零配置以及默认值

我们为 webpack 新增了一个 mode 配置项。Mode 有两个值:development 或者是 production,默认值是 production。Mode 是我们为减小生产环境构建体积以及节约开发环境的构建时间提供的一种优化方案。

如果想要了解更多 mode 配置项的内容,大家可以看看我们之前的一篇文章: webpack 4: mode 和优化

另外,entryoutput 这些配置项也都有默认值了。这意味着你不需要每次都配置它们了,当然包括 mode。这可能意味着从现在开始,你的配置文件在我们做出如此巨大改变之后会变得非常小!

Legato 意味着毫无间隙地连续演奏每个节奏。

另外,我们提供零配置平台来扩展。webpack 最大的一个特色就是可扩展性。最终我们实现的零配置平台会是什么样子呢?当我们实现了 webpack presets 功能后,这意味着你可以基于零配置平台配置你自己,公司,甚至是社区的工作流配置用以继承直接使用。

产品阶段的构建

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

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

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: __dirname   "/app/main.js",
  output: {
    path: __dirname   "/build",
    filename: "bundle.js"
  },

  module: {
    loaders: [
      {
        test: /.json$/,
        loader: "json"
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      },
      {
        test: /.css$/,
        loader: 'style!css?modules!postcss'
      }
    ]
  },
  postcss: [
    require('autoprefixer')
  ],

  plugins: [
    new HtmlWebpackPlugin({
      template: __dirname   "/app/index.tmpl.html"
    }),
  ],

}
//package.json
{
  "name": "webpack-sample-project",
  "version": "1.0.0",
  "description": "Sample webpack project",
  "scripts": {
    "start": "webpack-dev-server --progress",
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js --progress"
  },
  "author": "Cássio Zen",
  "license": "ISC",
  "devDependencies": {...},
  "dependencies": {...}
}

如果你正在使用 HtmlWebpackPlugin

在发布之前我们预留了一个月的时间 来升级所有的插件和 loader 以适配 webpack 4 的 API。然而,Jan Nicklas 因为工作原因没办法参加,因此我们不得不发布了一个 html-webpack-plugin 的 fork 版。你可以使用如下命令安装它:

JavaScript

$> yarn add html-webpack-plugin@webpack-contrib/html-webpack-plugin

1
$> yarn add html-webpack-plugin@webpack-contrib/html-webpack-plugin

当 Jan 本月底从海外工作回来时,我们会将我们的更新合并回 jantimon/html-webpack-plugin 仓库中!在此之前,如果你有任何问题,可以提交到这里

如果你是插件或 loader 的开发者,你可以查看我们的迁移指南:webpack 4: 插件/loader 迁移指南

优化插件

webpack提供了一些在发布阶段非常有用的优化插件,它们大多来自于webpack社区,可以通过npm安装,通过以下插件可以完成产品发布阶段所需的功能

  • OccurenceOrderPlugin :为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
  • UglifyJsPlugin:压缩JS代码;
  • ExtractTextPlugin:分离CSS和JS文件

我们继续用例子来看看如何添加它们,OccurenceOrder 和 UglifyJS plugins 都是内置插件,你需要做的只是安装它们

npm install --save-dev extract-text-webpack-plugin

在配置文件的plugins后引用它们

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: __dirname   "/app/main.js",
  output: {
    path: __dirname   "/build",
    filename: "bundle.js"
  },

  module: {
    loaders: [
      {
        test: /.json$/,
        loader: "json"
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      },
      {
        test: /.css$/,
        loader: ExtractTextPlugin.extract('style', 'css?modules!postcss')
      }
    ]
  },
  postcss: [
    require('autoprefixer')
  ],

  plugins: [
    new HtmlWebpackPlugin({
      template: __dirname   "/app/index.tmpl.html"
    }),
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin(),
    new ExtractTextPlugin("style.css")
  ]
}

 

✂ 再见 CommonsChunkPlugin

在新版中我们废弃并移除了 CommonsChunkPlugin,并且使用一些默认值以及更容易被复写的新 API optimize.splitChunks 来代替它。现在你可以在大部分场景中享受自动分块带来的便利了!

https://v.qq.com/iframe/player.html?vid=y0559vc6zin&tiny=1&auto=1

如果想要了解更多该 API 可以查看这篇文章:webpack 4: 代码分块以及分块优化

开始使用Webpack

初步了解了Webpack工作方式后,我们一步步的开始学习使用Webpack。

‍ 各框架 cli 工具支持怎么样了?

在过去的一个月我们也为每个框架的脚手架工作确保它们能支持 webpack 4。甚至最流行的库例如 lodash-es, RxJS 已经支持 sideEffects 选项,因此使用它们的最新版后你会发现打包体积会大幅度的减小。

AngularCLI 团队已经计划在近几周即将发布的大版本中直接使用 webpack 4!如果你想要知道最新进展,可以直接联系他们,并询问他们你能帮什么忙而不是直接询问它什么时候发布

正式使用Webpack

webpack可以在终端中使用,其最基础的命令是

webpack {entry file/入口文件} {destination for bundled file/存放bundle.js的地方}

只需要指定一个入口文件,webpack将自动识别项目所依赖的其它文件,不过需要注意的是如果你的webpack没有进行全局安装,那么当你在终端中使用此命令时,需要额外指定其在node_modules中的地址,继续上面的例子,在终端中属于如下命令

//webpack非全局安装的情况
node_modules/.bin/webpack app/main.js public/bundle.js

结果如下

图片 6

termialResult1

可以看出webpack同时编译了main.js 和Greeter,js,现在打开index.html,可以看到如下结果

图片 7

htmlResult1

有没有很激动,已经成功的使用Webpack打包了一个文件了。不过如果在终端中进行复杂的操作,还是不太方便且容易出错的,接下来看看Webpack的另一种使用方法。

代号: _Legato

今天我们愉快的宣布 webpack 4(Legato)正式发布了!你可以使用 yarn 或者 npm 获得它:

JavaScript

$> yarn add webpack --dev

1
$> yarn add webpack --dev

或者

JavaScript

$> npm i webpack --save-dev

1
$> npm i webpack --save-dev

生成Source Maps(使调试更容易)

开发总是离不开调试,如果可以更加方便的调试当然就能提高开发效率,不过打包后的文件有时候你是不容易找到出错了的地方对应的源代码的位置的,Source Maps就是来帮我们解决这个问题的。
通过简单的配置后,Webpack在打包时可以为我们生成的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是一个很好的选项,不过记得只在开发阶段使用它,继续上面的例子,进行如下配置

module.exports = {
  devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
  entry:  __dirname   "/app/main.js",
  output: {
    path: __dirname   "/public",
    filename: "bundle.js"
  }
}

cheap-module-eval-source-map方法构建速度更快,但是不利于调试,推荐在大型项目考虑da时间成本是使用。

本文由www.2003.com发布于计算机教程,转载请注明出处:webpack

关键词: