Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack的基础配置记录 #10

Open
Diazhao opened this issue Aug 13, 2019 · 3 comments
Open

webpack的基础配置记录 #10

Diazhao opened this issue Aug 13, 2019 · 3 comments

Comments

@Diazhao
Copy link
Owner

Diazhao commented Aug 13, 2019

webpack4.x常用配置

webpack4.x可以提供零配置运行项目,提供了一些默认的配置。但都不足以支撑我们的项目,要想让我们的项目健康的跑起来,还是需要对webpack的配置有一个简单的了解。以下说明都建立在已经安装了webpack的前提下。

First. 运行npm run dev的时候,指定自己的配置文件

在项目的package.json中,通过以下脚本指定到运行的webpack文件,并且可以带上运行的参数

"scripts": {
  "build": "webpack --config prod.config.js",
  "dev": "webpack-dev-server --config dev.config.js"
}

一般在项目中,我们都会将构建与本地运行的配置文件分开配置,用以执行不同的配置项。

Second. 配置项说明(只在项目中遇到过处理过的问题)

mode -- 为本次编译提供模式信息

module.exports = {
  mode: 'production' //'development', 'none'
};

通过process.env.NODE_ENV来取值,在脚本中通过这个变量来区分此次编译是打包发布还是本地调试

alias -- 别名

alias配置是在resolve模块中, 通过配置别名可以让我们在项目中快速的找到一些静态的不变化的变量引入。例如,

alias: {
	'jquery': resolve('src/assets/lib/jquery'),
	'@': resolve('src'),
	'utils': resolve('src/assets/js/utils')
}

通过这些配置以后,我们就可以在项目中直接引入使用,例如想引用utils的时候,使用如下代码,import utils from utils即可,不用再指定到文件的具体目录。
第二点,一般与alias配合使用的是webpackprovidePlugin.通过这个插件,可以默认的为我们引入对应的模块,我们可以在代码中直接使用,而不用再通过importorrequire来引入.例如

new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery'
});

通过这两个配置我们就可以在项目中愉快的引入第三方静态包了。后续这些第三方包如何打包输出,会有进一步的讨论。

@Diazhao
Copy link
Owner Author

Diazhao commented Aug 13, 2019

output --> publicPath, assetsPath等几个输出路径的区别

@Diazhao
Copy link
Owner Author

Diazhao commented Aug 19, 2019

webpack中的路径相关配置

‘assetsPublicPath’的来由与publicPath

最开始在看vue-cli脚手架生成的工程的时候,在打包的配置中看到了这个配置项。所以一直就记着了,并没有深究他在webpack配置的代码中被转换成了哪个配置项。
其实这个配置项就是publicPath
publicPath起到了一个什么作用呢?
我们来看下设置了publicPath配置项打包后的html模板文件,

    output:{
        publicPath: '/TTC/' //这里要放的是静态资源CDN的地址(一般只在生产环境下配置)
    },
    <body>
        <div id=container></div>
        <script type=text/javascript src=/TTC/index.c727d92d6a8cf4bad9f3.js?c727d92d6a8cf4bad9f3></script>
    </body>

看到我们的静态资源访问路径被加上了/TCC的前缀。其作用不止体现在模板文件中,而是所有按需加载的资源或者外部资源的访问都会自动加上这个前缀,以便我们能够顺利的访问到需要访问的资源。

webpack-dev-server中的publicPath与contentBase

这其中的publicPath决定了我们的静态资源可以在浏览器中以何种路径被访问。默认值是/,如果我们设置了一个值,webpack文档建议我们webpack-dev-server中的值要与output中的一致。
contentBase,只有当我们想为静态文件提供访问服务的时候需要设置的选项。
dev-server中的publicPath同时设置的话以publicPath为准

@Diazhao
Copy link
Owner Author

Diazhao commented Aug 20, 2019

resolve模块

resolve模块定义了webpack该如何解析我们的模块。
常用的主要有两个方面。

    resolve: {
        extensions: [".js",".jsx", ".css", ".json"],
        alias: {
            '@': resolve('src')
        }
    },
  1. extensions,也就是文件后缀扩展名。通过以上extensions的配置,我们可以在引入模块的时候,不必写以上几种类型的后缀名称. 例如有一个utils.js,在引入的时候,只需要import utils from ./utils即可。
  2. alias,给我们相应的模块添加别名。可以在工程中快速的引用。
    alias配置是在resolve模块中, 通过配置别名可以让我们在项目中快速的找到一些静态的不变化的变量引入。例如,
    alias: {
        'jquery': resolve('src/assets/lib/jquery'),
        '@': resolve('src'),
        'utils': resolve('src/assets/js/utils')
    }

通过这些配置以后,我们就可以在项目中直接引入使用,例如想引用utils的时候,使用如下代码,import utils from 'utils'即可,不用再指定到文件的具体目录。

  1. 我觉得还需要说下mainFiles这个配置。The filename to be used while resolving directories,官网释义。默认值是[string]: ['index'].通过这个配置,我们可以指定文件夹内部默认的入口文件,引用时只需要到文件夹名称即可。

module模块,配置项目中的不同类型的模块被如何treated

配置babel-loader
    {
        test: /\.jsx$/,
        use: ['babel-loader'],
        include: [resolve('src')], //限制范围,提高打包速度
        exclude: /node_modules/
    },

babel的配置采取配置与webpack配置分离的形式来。在.babelrc文件中配置。不同的配置可以参考@babel官网

{
    "presets": ["@babel/preset-env", {"useBuiltIns": "usage"}, "@babel/preset-react"],
    "plugins": ["@babel/plugin-transform-runtime"]
}

以上配置表示babel解析es6以及react的语法,并且只在运行有需要的时候进行polyfill转义。可以缩小我们的打包体积.

配置加载样式文件loader

通过以下配置,加载样式文件,并且把工程中的css样式相关代码都提取出来到单独的css文件中

    {
        test: /\.(sa|le|c)ss$/,
        use: [
            {
                loader: MiniCssExtractPlugin.loader,
                options: {
                    hmr: process.env.NODE_ENV === 'development'
                }
            },
            'css-loader',
            'less-loader',
            'sass-loader'
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[hash].css',
            chunkFilename: '[id].[hash].css'
        })
    ]

还有url-loader, file-loader等一系列的常用loader,以及extract-loader, i18n-loader等很有用的loader.同样的,loader也提供了一系列的接口出来供开发者编写属于自己的loader

optimization模块

用到最多的是在webpack4.x中公用代码的抽离。

    optimization: { //webpack4.x的最新优化配置项,用于提取公共代码
        splitChunks: {
            chunks: 'all',
        }
    },

使用DllPlugin抽离不经常变更的第三方库

使用DllPlugin需要同时结合DllReferencePlugin一起使用。
DllPlugin需要在webpack.dll.config.js中使用
DllReferencePlugin需要在我们的webpack.base.config.js中使用
这个插件的大致思想分一下几个步骤

  1. 使用webpack.dll.config.js中的配置把第三方公用的库抽离出来放在static文件夹中(这里我放在了这个文件夹,其实可以放在任意文件夹中,只要保证后期可以访问到即可).生成了对应的manifest.json文件
  2. DllReferencePlugin插件结合上一步生成的manifest.json文件判定库是否已被抽离,抽离的库不在进行打包操作。
  3. 通过插件add-asset-html-webpack-plugin或者手动修改模板index.html文件,引用刚才输出的static文件夹对应的文件即可

webpack.dll.config.js配置如下

    module.exports = {
        mode: 'production',
        entry: {
            dll: ["echarts", "react", "react-dom"]
        },
        output: {
            path: path.resolve(__dirname, "../static/", 'dll'),
            filename: '[name].dll.js',
            library: '[name]_[hash]',
            libraryTarget: 'this'
        },
        plugins: [
            new webpack.DllPlugin({
                context: process.cwd(),
                path: path.join(__dirname, "../", "[name]-mainfest.json"),
                name: "[name]_[hash]"
            })
        ]
    }

webpack.base.config.js中增加如下插件

    new webpack.DllReferencePlugin({ 
        manifest
    }),

同时修改index.html模板文件

<script src="../static/dll/dll.dll.js"></script>

然后运行项目即可.

plugins模块

常用的有html-webpack-plugin, copy-webpack-plugin, clean-webpack-plugin等

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant