程序员

webpack教程_由浅入深的webpack配置

2017-07-30  本文已影响0人  哔咖丘

前言

少侠,愿你页底归来,已习得webpack精要。

那些你熟悉的概念

那些你熟悉的概念

入口起点

module.exports = {
    entry: './usage/index.js'
}
module.exports = {
    entry: ['./plugins/hello.js','./usage/index.js']
}

问题:数组语法跟主入口文件引入依赖文件有什么区别?

module.exports = {
    entry: {
        "usage.index": './usage/index.js',
        "usage.main": './usage/main.js'
    }
}

输出

const path = require('path');
module.exports = {
    entry: {
        "usage.index": './usage/index.js',
        "usage.main": './usage/main.js'
    },
 
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'usage/dist/js'),
        publicPath: '/js/'
    }
}

说明:
publicPath:声明资源对外链接,如上配置可以通过<script src="/js/usage.index.js">去访问你的js资源。

加载器(Loaders)

loader是对应用程序中的资源进行转换。他们是函数,可以将文件资源作为参数来源,经过一番处理后返回性的文件资源。类似于fis3或者gulp中的插件

const path = require('path');
module.exports = {
    entry: {
        "usage.index": './usage/index.js',
        "usage.main": './usage/main.js'
    },
  
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'usage/dist/js'),
        publicPath: '/js/'
    },
    rules: [{
        test: /\.css$/,
        use: [
            'style-loader',
            'css-loader?modules',
        ]
    }]
}
require('style-loader!css-loader?modules!./styles.css');
 
webpack --module-bind jade --module-bind 'css=style!css'

说明:webpack通过「!」区分加载器。

插件

插件是webpack的支柱功能,它的目标在于解决loader无法实现的其他事。webpack插件是一个具有apply 属性的javascript对象。

const path = require('path');
module.exports = {
    entry: {
        "usage.index": './usage/index.js',
        "usage.main": './usage/main.js'
    },
  
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'usage/dist/js'),
        publicPath: '/js/'
    },
    rules: [{
        test: /\.css$/,
        use: [
            'style-loader',
            'css-loader?modules',
        ]
    }],
     
    plugins: [
        new ManifestPlugin({
            fileName: 'manifest.json',
            basePath: './build/',
            seed: {
                name: 'My Manifest'
            }
        })
    ]
}

说明:这里使用的是一个缓存插件,具体的作用我们后续讲解。

那些我模糊的名词

那些我模糊的名词

模块

依赖图表

从入口点开始,webpack 递归地构建一个依赖图表,这个依赖图表包括你应用所需的每个模块,然后将所有模块打包为少量的包(bundle) - 通常只有一个包 - 可由浏览器加载。

构建目标

因为服务端可浏览器端代码都可以用JavaScript编写,因此,webpack提供了 nodeweb 两种类型的构建,我们可以通过设置构建目标实现不同类型的构建。

const path = require('path');
module.exports = {
    target: 'node',  // 默认是web,可以省略
    entry: {
        "usage.index": './usage/index.js',
        "usage.main": './usage/main.js'
    },
  
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'usage/dist/js'),
        publicPath: '/js/'
    }
    // ...
}

通过 module.exports = [clientConfig, serviceConfig],的方式实现多target配置。

const path = require('path');
const webpack = require('webpack');
 
module.exports = {
    target: 'node',  // 默认是web,可以省略
    entry: {
        "usage.index": './usage/index.js',
        "usage.main": './usage/main.js'
    },
  
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'usage/dist/js'),
        publicPath: '/js/'
    },
     
    plugins: [
        // 开启全局的模块热替换(HMR)
        new webpack.HotModuleReplacementPlugin(),
        // 当模块热替换(HMR)时在浏览器控制台输出对用户更友好的模块名字信息
        new webpack.NamedModulesPlugin(),
    ],
 
    rules: [{
        test: /\.css$/,
        use: [
            'style-loader',
            'css-loader?modules',
        ]
    }],
    // ...
}

你的入口index.js:

import _ from 'lodash';
import styles from './css/main.css';
function component () {
    let element = document.createElement('div');
    element.innerHTML = _.join(['hello', 'webpack'],' ');
    return element;
}
document.body.appendChild(component());

说明:在该配置下,修改 mian.css 样式表后,不需要刷新浏览器页面即可看到更新。
问题:在入口index.js文件中引入样式表,那么最终样式表会跟js文件一起打包,如此会影响到页面的加载性能。那么要如何分离呢?
Answer: 使用 extract-text-webpack-plugin 解决你的问题。

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

module.exports = {
  // ...
  plugins: [
    new ExtractTextPlugin('dist/style.css')  // 不支持热替换
  ],
  module: {
    rules: [{
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        use: 'css-loader'
      })
    }]
}

说明:该插件作用之后,会将入口文件中引用的 main.css 构建成 dist/style.css 。另,该插件不支持热替换,亦即在本地开发过程,使用热替换达到独立模块热替换,在build过程开启开插件做分离构建。

那些我们遇到的问题

那些我们遇到的问题

如何做精准的构建

const path = require('path');
module.exports = {
    entry: {
        "usage.index": './usage/index.js',
        "usage.main": './usage/main.js'
    },
  
    output: {
        filename: '[name].[chunkhash].js',  // 每一个文件拥有自己唯一的hash值,不要在开发环境下使用,这会增加编译时间,不能与HMR插件共同使用
        path: path.resolve(__dirname, 'usage/dist/js'),
        publicPath: '/js/'
    }
}

说明:在该配置下,只会对有作更改的入口文件进行构建。区分:filename: '[name].[hash].js',这种配置下,所有的入口文件共享一个hash值,即其中某个入口文件更改之后,会对所有的入口文件做更改。
问题:重复构建导致许多的垃圾文件?文件名每次变更,html引入麻烦?这些....,交给webpack插件,都不是问题!

plugins: [
    new ManifestPlugin({
        fileName: 'manifest.json',
        basePath: './build/',
        seed: {
            name: 'My Manifest'
        }
    })
]

使用了插件,会生成一个映射文件,从这里,可以取到对应的文件名:

缓存文件映射表

webpack js资源断点调试技巧

module.exports = {
    devtool: 'source-map',// 可断点调试
}
上一篇 下一篇

猜你喜欢

热点阅读