Webpack入门指南: 入口,输出,加载器和插件

Posted 奇舞周刊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Webpack入门指南: 入口,输出,加载器和插件相关的知识,希望对你有一定的参考价值。


编者按:本文由Nero0在众成翻译平台上翻译。祝大家周末愉快,每天都有好心情~


(图片来自网络)

前端开发已经变成模块化的方式,代码的封装和结构也相应地提高了。工程化变成每一个项目非常关键的一部分,关于前端工程化的选择也非常的多。

这几年Webpack获得了很高的人气,因为它强大的功能和可扩展性,但是有一些开发者在编写配置文件的时候会感觉疑惑,较难去适应webpack的配置方式。

我们将从一个空配置文件开始,编写一些简单的配置,一步步的去完整的打包一个项目。这篇文章假定你们了解基本的 CommonJS 语法和模块的工作方式。

概念

不像其他的打包工具,Webpack 的魅力在于聚合你所有的项目依赖(不仅仅是代码,还包括其他资源文件)生成一个依赖关系网。

刚开始,这些事情可能看起来很奇怪:一个.js文件需要加载一个样式表,或者一个样式表文件检索一个被修改为模块的图片文件,但是对于 Webpack来说,这样可以让它了解你的程序包里都有哪些东西,并帮助你去转变转变和优化它们。

安装

首先添加用来初始化的npm包

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

接下来在项目根目录创建一个 webpack.config.js 文件,添加两条脚本命令到 package.json 文件中用作开发模式和生产模式的代码打包。

"scripts": {

  "start": "webpack-dev-server",

  "build": "webpack"

}

Webpack 命令会按照我们刚创建的配置文件执行,除非我们指出其他操作。

入口

有很多方式来指定我们的代码“入口点”,这个“入口点”将会是我们依赖关系网的根节点。

最简单的方式是传一个字符串:

var baseConfig = {

  entry: './src/index.js'

};

也可以传一个对象,以防我们以后可能需要不止一个入口的情况。

var baseConfig = {

  entry: {

    main: './src/index.js'

  }

};

我推荐使用后者,当项目逐渐壮大之后这样的扩展性更好。

输出

Webpack中的输出是一个对象,包含我们打包后的程序和资源将要去到的路径,以及它们采用的名称。

var path = require('path');


var baseConfig = {

  entry: {

    main: './src/index.js'

  },

  output: {

    filename: 'main.js',

    path: path.resolve('./build')

  }

};


// export configuration

module.exports = baseConfig;

如果你想使用对象来定义入口,而不是用字符串写死输出文件的名称,可以这么做:

output: {

  filename: '[name].js',

  path: path.resolve('./build')

}

这样当新的条目添加进来时,Webpack会使用它们的key值来定义文件名。

当有了这些简单的配置以后,我们已经可以跑起来简单的服务,并在本地开发时使用 npm startnpm run budil来打包我们的代码。webpack-dev-server 会监控你的代码,当项目的依赖关系中某一些环节发生改变的时候,网站会自动重载。

加载器

Webpack 存在的目标就是处理我们所有的文件依赖。

// index.js file

import helpers from '/helpers/main.js';


// Hey Webpack! I will need these styles:

import 'main.css';

这是啥?在javascript里面require一个css文件?是的!但是打包器只能准备好处理Javascript的依赖关系。 这是加载器介入的地方。

加载器提供了一种很简单的方式来拦截我们的依赖,并在打包之前提供预处理。

var baseConfig = {

  // ...

  module: {

    rules: [

      {

        test: /* RegEx */,

        use: [

          {

            loader: /* loader name */,

            query: /* optional config object */

          }

        ]

      }

    ]

  }

};

为了让加载器工作,我们需要一个正则表达式来定义我们需要修改的文件,以及一个字符串或数组用来申明我们需要使用的加载器。

样式

为了让Webpack可以处理样式,我们需要安装css和style加载器。

npm install --save-dev css-loader style-loader

css加载器将会把样式文件翻译成依赖文件,style加载器将会自动添加 `` 标签当打包后的代码在页面上被加载时。

var baseConfig = {

  entry: {

    main: './src/index.js'

  },

  output: {

    filename: '[name].js',

    path: path.resolve('./build')

  },

  module: {

    rules: [

      {

        test: /\.css$/,

        use: [

          { loader: 'style-loader' },

          { loader: 'css-loader' }

        ]

      }

    ]

  }

};

在这个例子里面,main.css将先经过css加载器的处理,然后是style加载器

预处理器

添加对LESS或其他css预处理器也非常简单,只需要安装相应的加载器,并添加到规则中。

rules: [

  {

    test: /\.less$/,

    use: [

      { loader: 'style-loader' },

      { loader: 'css-loader' },

      { loader: 'less-loader' }

    ]

  }

]

编译

JavaScript也可以被加载器转化,比如我们可以使用Babel加载器来编译脚本文件。

rules: [

  {

    test: /\.js$/,

    use: [

      { loader: 'babel-loader' }

    ]

  }

]

图片

Webpack有一个很棒的特性,它可以在样式表里检测出url()语句,让加载器对图片文件或链接本身做出一些改变。

// index.less file


@import 'less/vars';


body {

  background-color: @background-color;

  color: @text-color;

}


.logo {

  background-image: url('./images/logo.svg');

}

通过添加这条规则,我们可以应用文件加载器来拷贝文件,或使用url-加载器,将图片替换为base64字符串,除非它超过字节限制,在这种情况下,它将用相对路径替换url语句,并将文件复制到输出位置。

{

  test: /\.svg$/,

  use: [

    {

       loader: 'url-loader',

       query: { limit : 10000 }

    }

  ]

}

加载器可以通过传递query对象来配置,比如我们可以配置加载器内联文件,当文件不超过10Kb的时候。

通过这样的方式来管理打包进程,我们只需要include一些必要的资源,而不是去移动有大量文件的资源文件夹,甚至很多文件你的项目根本用不上。

如果你使用 React或者类似的库,在组件内你可以使用svg-inline-loader来加载.svg文件。

插件

Webpack在打包大多数类型的资源的时候有一些默认的操作,当加载器的功能不够用的时候,我们可以使用一些插件来扩展Webpack的功能。

举例来说,Webpack默认会将样式文件打包插入,但是我们可以通过引入插件来改变这个行为。

提取资源

一个常见的用法是提取出生成好的样式文件,并且就像我们通常加载那样使用``标签。

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


var lessRules = {

  use: [

    { loader: 'css-loader' },

    { loader: 'less-loader' }

  ]

};


var baseConfig = {

  // ...

  module: {

    rules: [

      // ...

      { test: /\.less$/, use: ExtractTextPlugin.extract(lessRules) }

    ]

  },

  plugins: [

    new ExtractTextPlugin('main.css')

  ]

};

生成一个 index.html 文件

当构建一个单页面应用的时候,我们通常需要一个.html文件来承载页面。

HtmlWebpackPlugin可以自动创建index.html 文件,添加打包生成的script标签。同时也支持模板语法,可配置性很高。

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


var baseConfig = {

  // ...

  plugins: [

    new HTMLWebpackPlugin()

  ]

};

为生产模式构建

定义环境

很多库引入了报警机制,这在开发模式中非常有用,但是在生产模式中没有用(打包上线),还会增加线上包的体积。

Webpack 提供了内建的插件可以在打包过程中设置一个全局变量。

var ENV = process.env.NODE_ENV;


var baseConfig = {

  // ...

  plugins: [

    new webpack.DefinePlugin({

      'process.env.NODE_ENV': JSON.stringify(ENV)

    })

  ]

};

我们现在需要在命令中指定环境:

"scripts": {

  "start": "NODE_ENV=development webpack-dev-server",

  "build": "NODE_ENV=production webpack"

}

process.env.NODE_ENV将会被一个字符串替换,使得压缩器可以去掉那些没用的开发分支。

在代码中引入警告会非常有用,当你的团队没有进入生产模式的打包进程。

if (process.env.NODE_ENV === 'development') {

    console.warn('This warning will dissapear on production build!');

  }

压缩

在生产模式中,我们需要给用户尽可能快的产品。通过修改代码,减少不必要的字符,捡回减少我们最后打包出来的文件大小,提升加载速度。

一个很有用的工具是 UglifyJS, 在Webpack中提供了一个内建的插件来处理我们的代码。

// webpack.config.js file

var ENV = process.env.NODE_ENV;


var baseConfig = {

  // ...

  plugins: []

};


if (ENV === 'production') {

  baseConfig.plugins.push(new webpack.optimize.UglifyJsPlugin());

}

总结

Webpack 配置文件非常有用,并且可以根据你的需求改变文件的复杂度。多注意去好好管理,当你的项目变得复杂的时候,配置文件可能也会变得难以管理。

在这篇文章里面,我们从一个空的配置文件开始,逐步完成了可以本地开发和发布生产代码的功能配置。Webpack的功能还需要更多的探索,这些基本概念将会帮助你更熟悉和了解Webpack。

如果你想要更深入,我推荐Webpack official documentation,它在第二次发布中更新了很多新的内容。


奇舞周刊

——————————————————

领略前端技术 阅读奇舞周刊


长按二维码,关注奇舞周刊


以上是关于Webpack入门指南: 入口,输出,加载器和插件的主要内容,如果未能解决你的问题,请参考以下文章

Webpack配置信息入门

webpack 从入门到放弃

# Webpack 学习Webpack 搭建 Vue项目

# Webpack 学习Webpack 搭建 Vue项目

webpack简单配置

Webpack 是怎样运行的?