码云 IDEA 插件最新版本发布,支持 Pull Request

Janking / Infinite-f2e-clubJavaScriptMIT

Watch 25 Star 9

Webpack入门指南

待办的
zzj 成员  创建于

前言

本文是基于昕哥的Webpack学习系列(一)初学者使用教程 这篇文章做构建。可能昕哥的文章是基于Mac环境,我是windows环境,在学习时遇到了很多坑,询问昕哥,他让我搞个基于windows环境的,我想了想,正好这几天需求不多,webpack3.0也来了,那就干吧!推陈出新,本文对配置细节以及常见报错会有注解,增加了babel以及图片打包,基于webpack3.0环境。希望能为想入门webpack的小伙伴提供一个思路。

什么是webpack?

Webpack 是当下最热门的前端资源模块化管理和打包工具。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔,等到实际需要的时候再异步加载。通过 loader 的转换,任何形式的资源都可以视作模块,比如 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 SASS 等。

webpack是基于node.js环境的前端自动化打包工具,本文默认你已有一定使用node和npm安装的基础。

##安装

1.1 webpack安装

首先新建一个练习文件夹demo,在文件中打开命令终端,输入下列指令即可安装webpack

//全局安装

npm install -g webpack

//安装到项目文件夹

npm install --save-dev webpack

安装完之后,demo里会多一个node_modules文件夹。

接下来输入

npm init

会自动创建package.json文件。安装的时候一路回车即可,需要修改后面再进入package.json文件编辑。

package.json文件是webpack的骨架,在里面可以看到各个关键节点,设置快捷命令等。

1.2 文件夹部署

安装好上面的东西,我们开始往demo文件夹塞东西,新建distsrc文件夹、webpack.config.js配置文件来模拟开发环境。最终目录如下:

demo                      //webpack的模拟开发文件夹
   | - webpack.config.js  //配置webpack出入口、插件、loader
   | - node_modules
   | - dist               //打包输出文件夹
   | - src            	  //开发资源文件夹
     | - webpack.js     //配置webpack引入资源
     | - index.html     /*   基础html文件
     | - index.js            基础js文件
     | - index.css           基础css文件
     | - index.scss          基础scss文件            
     | - images              基础图片文件夹   */
         | - img1.png
         | - img2.png

1.3 配置webpack.config.js

var path = require('path')
var webpack = require('webpack')
module.exports = {
  // bundle入口
  entry: ['./src/webpack'],
  // bundle输出
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js' //可重命名
  }
}

运行

按上面步骤安装后,运行

webpack

即可打包,我们可以看到dist文件夹中生成了bundle.js,此时还未压缩,大小为3k。QQ截图20170622162129

2.1 多入口

我们看到打包后生成了一个js文件,那假如我们项目需求生成几个不同类别的js呢?例如当js文件数量多,就模块化打包后按需加载。

例如:webpack.js和webpack2.js要作为一个模块,而index.js和index2.js要作为另一个模块。这时entry和output就要换一种写法了:

配置webpack.config.js:

var path = require('path')
var webpack = require('webpack')
module.exports = {
  // 多入口
  entry: {
        name1: ['./src/webpack','./src/webpack2'],
        name2: ['./src/index','./src/index2']
  },
  // 输出
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js' //可重命名
  }
}

运行打包后可以在dist里看到两个name.js

QQ截图20170623105907

js模块化分离打包成功。

2.2 UglifyJsPlugin

UglifyJsPlugin是webpack自带的核心插件,无需安装,无需声明require直接使用。它运行UglifyJs来压缩输入文件。

配置webpack.config.js,增加plugins项,里面放置插件

var path = require('path')
var webpack = require('webpack')
module.exports = {
  // bundle入口
  entry: ['./src/webpack'],
  // bundle输出
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js' //可重命名
  },
  //插件
  plugins: [
  		//压缩
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
   ]
}

更改配置后,运行webpack打包,可以看到大小1k(实际是500多字节),压小了不少。

QQ截图20170622162857

loader

Webpack 本身只能理解、处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。通过使用不同的loader,webpack通过调用外部的脚本或工具可以对各种各样的格式的文件进行处理。

总结:Webpack 只能看懂JavaScript ,对于其他静态文件,需要用loader帮助理解转换。

Loaders的配置选项包括以下几方面:

  • test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)
  • loader:loader的名称(必须)
  • include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
  • query:为loaders提供额外的设置选项(可选)

介绍完毕,撸起来!

3.1 编译CSS

命令安装 css-loader

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

关于loaders的放置顺序:loader解析是从右向左,css-loader用于解析,而style-loader则将解析后的样式嵌入js代码。

配置webpack.config.js,增加module项,里面放置css-loader

var path = require('path')
var webpack = require('webpack')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ],
    //组件loader
    module: {
    loaders: [{
       // css转换
       test: /\.css$/,
       loaders: ['style-loader', 'css-loader']
    }]
  }
}

配置webpack.js文件,引入index.css

require('./index.css') 

运行 webpack 打包,无报错即编译成功,可以在bundle.js文件里看到压缩进去的css文件。

**注意:**这里有个小坑,网上很多资料都说可以省略"-loader",即:

loaders: [{
       // css转换
       test: /\.css$/,
       loaders: ['style', 'css']
}]

在windows环境我们按这种写法打包一下,会发现报错:

编译css不加-loader时打包报错

可以看到,里面提到不再允许省略"-loader"的写法。所以当我们写loader名称时不要简写。

3.2 编译sass(scss)

命令安装 sass-loader

npm install --save-dev style-loader sass-loader

发现有飘红信息:node-sass

缺少 node-sass 依赖,我们再敲一行命令装上去就可以了:

npm install --save-dev style-loader node-sass

然后 npm list 命令看看有没有安装成功,后面带别的名称即可查其他分支。如sass-loader

npm list node-sass

配置webpack.config.js,增加sass-loader

var path = require('path')
var webpack = require('webpack')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ],
    //组件loader
    module: {
        loaders: [ 
            // css转换
            {
                test: /\.css$/, 
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /\.scss$/,
                loaders: ['style-loader', 'css-loader', 'sass-loader']
            }
        ]
    }
}

配置webpack.js文件,引入index.scss

require('./index.css') 
require('./index.scss') 

运行 webpack ,没报错就是编译sass成功了。编译less同理,不赘述。

plugins

顾名思义,Plugins 就是webpack的插件。loader只能对静态文件做处理,而Plugins 不处理单个文件,而是作用于整个构建流程。上面提到的UglifyJsPlugin,也是插件的一种。

4.1 分离CSS和JavaScript ——Extract Text Plugin

进行到这里,我们会发现,打包之后的css和js都集合在一起,那到时候引入到页面上,是放到头部,还是尾部呢?显然都是不可取的:无论放头部和尾部,js都会阻塞页面渲染。而插件 Extract Text Plugin 可以帮助我们分离css和js。

命令安装:

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

配置webpack.config.js

头部增加Extract Text Plugin插件引入,在plugins那里new一个你想输出的样式文件,最后在loader那增加插件写法。

var path = require('path')
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
    // bundle入口
    entry: ['./src/webpack'],
    // bundle输出
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js' //可重命名
    },
    //插件
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new ExtractTextPlugin("styles.css")
    ],
    //组件loader
    module: {
        loaders: [ 
            // css转换
            {
                test: /\.css$/, 
                loaders: ['style-loader', 'css-loader']
            },
            // sass转换 
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract('style-loader', 'css-loader', 'sass-loader')
            }
        ]
    }
}

**注意:**没错,这里又有坑。

先运行打包一下:QQ图片20170622183908

日常报错。所幸日志里面有提醒我们:你的代码老掉牙了,换种写法吧!

来,把sass转换那部