SunXinFei / sunxinfei.github.io

前后端技术相关笔记,已迁移到 Issues 中
https://github.com/SunXinFei/sunxinfei.github.io/issues
32 stars 3 forks source link

webpack4.1.1 开发、生产环境配置 #7

Open SunXinFei opened 6 years ago

SunXinFei commented 6 years ago

webpack error about 'optionsSchema.definitions.output.properties.path.description'

/home/uli/project/node_modules/webpack-cli/bin/config-yargs.js:89
                                describe: optionsSchema.definitions.output.properties.path.description,
                                                                           ^

TypeError: Cannot read property 'properties' of undefined
    at module.exports (/home/uli/project/node_modules/webpack-cli/bin/config-yargs.js:89:48)
    at /home/uli/project/node_modules/webpack-cli/bin/webpack.js:60:27
    at Object.<anonymous> (/home/uli/project/node_modules/webpack-cli/bin/webpack.js:515:3)
    at Module._compile (internal/modules/cjs/loader.js:723:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:734:10)
    at Module.load (internal/modules/cjs/loader.js:620:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
    at Function.Module._load (internal/modules/cjs/loader.js:552:3)
    at Module.require (internal/modules/cjs/loader.js:659:17)
    at require (internal/modules/cjs/helpers.js:22:18)

这个错误主要是webpack的version导致的,可以写死webpack的版本号,如 "webpack": "4.19.0",注意没有^这个符号,重新npm install安装依赖即可 参考文献 https://techoverflow.net/

SunXinFei commented 6 years ago

关于devServer中的proxy代理配置

webpack-dev-server中的proxy可以实现前后端代码分离。

SunXinFei commented 6 years ago

关于CleanWebpackPlugin

CleanWebpackPlugin可以清除生产环境下面的文件,一般output的路径和clean的路径一致即可,也可以指定只清除某几个文件夹,或者通过option的ignore来不清除某几个。但是有时候有特殊的需求,比如清除不在根目录的文件,一般情况下allowExternal: true再配合清除的相对路径 ../dist,可以满足大部分的需求,还有一种就是需要去设置root,但是必须是绝对路径,相对路径会不起作用: { // Absolute path to your webpack root folder (paths appended to this) 必须是绝对路径,windows下面如D:/scm/prod-dist”,mac中的”/Users/UserName/scm/prod-dist“ // Default: root of your package 默认是package的根目录 root: __dirname,

// Write logs to console. verbose: true,

// Use boolean "true" to test/emulate delete. (will not remove files). // Default: false - remove files dry: false,

// If true, remove files on recompile. // Default: false watch: false,

// Instead of removing whole path recursively, // remove all path's content with exclusion of provided immediate children. // Good for not removing shared files from build directories. exclude: [ 'files', 'to', 'ignore' ],

// allow the plugin to clean folders outside of the webpack root. 允许清除根目录之外的文件夹 // Default: false - don't allow clean folder outside of the webpack root 默认是false-不允许清除根目录之外的文件夹 allowExternal: false

// perform clean just before files are emitted to the output dir // Default: false beforeEmit: false }

SunXinFei commented 6 years ago

HtmlWebpackPlugin

  1. 当有多个html页面入口时,则需要循环new HtmlWebpackPlugin对象,并push进webpackPlugin配置数字中使用 2.inject: false 不再对html进行修改 3.html中支持模板 ` <% for (var chunk in htmlWebpackPlugin.files.chunks) {
    var tmpEntryArr = htmlWebpackPlugin.files.chunks[chunk].entry.split("/"); var indexJs = tmpEntryArr[ tmpEntryArr.length-1]; %>

    <% } %> `

SunXinFei commented 6 years ago

关于file loader

在实际的项目中,有某种情况是html和img或字体文件等资源文件没在同一级目录,file loader可以修改资源文件的输出目标文件夹,context修改默认的路径上下文,修改了context从而[path]就相应的进行了改变,不过更多的时候我们还需要修改资源的引用路径,也就是修改publicPath,


{
                    test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
                    exclude: /favicon\.png$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                context: path.resolve(__dirname, 'src/'),//修改[path]为根目录下的src/
                                name: '[path][name].[hash:8].[ext]',
                                publicPath: function(url) {
                                    var urlArr = url.split("/");
                                    return urlArr[urlArr.length-1];
                                  },
                            }
                        }
                    ]
                }
`
SunXinFei commented 5 years ago

postcss-px2rem or postcss-plugin-px2rem 在webpack4 中的less 配置

* 注意:如果loader中使用了cssnano这个插件,会导致less中的注释被去掉,从而导致/px/ /no*/ 不起作用

module: {
            rules: [
                {
                    test: /\.css$/,
                    //css和js不进行代码分离,所以注释掉ExtractTextPlugin
                    // use: ExtractTextPlugin.extract({
                    use: ['style-loader', 'css-loader', {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [
                                require('autoprefixer'),
                                //require('cssnano')
                            ],
                        }
                    }]
                    //     fallback: 'style-loader'
                    // })
                },
                {
                    test: /\.less$/,
                    // use: ExtractTextPlugin.extract({
                    use: ['style-loader', 'css-loader', {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [
                                require('autoprefixer'),
                                //require('cssnano'),<=会去掉注释,需要屏蔽掉
                                require('postcss-px2rem')({
                                    remUnit: 75
                                }),
                                // require('postcss-plugin-px2rem')({
                                  //  rootValue:10,
                                 //   minPixelValue:2,
                                //})
                            ],
                        }
                    }, 'less-loader']
                    //     fallback: 'style-loader'
                    // })
                }
            ]
        },
SunXinFei commented 5 years ago

ExtractTextPlugin在webpack4中的坑

如果想实现css抽离,需要进行如下配置,适配与webpack4以上,

  1. 安装需要指定为@next版本 npm install extract-text-webpack-plugin@next --save-dev
  2. webpack配置中
    
    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    plugins: [
    //https://github.com/jantimon/html-webpack-plugin#configuration
            new HtmlWebpackPlugin({
                filename: `index.html`,
                template: './index.html',
                inject: 'body'
            }),
            new ExtractTextPlugin('main.[hash:8].css') //<=这个为要输出的文件名,会添加到html中
        ],

module: { //开发和生产中使用的loader rules: [ { test: /.(css|less)$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader',"postcss-loader",'less-loader' ] }) } ]}


## webpack打包优化

- 使用高版本webpack4

> - V8带来的优化(for of  替代forEach、Map和Set替代Object、includes替代indexOf)
> - 默认使用更快的md4hash算法
> - webpacks AST可以直接从loader传递给AST减少解析事件
> - 使用字符串方法替代了正则表达式

- 多线程/多实例构建:thread-loader

- 缩小打包作用域:

> - exclude/include确定loader范围
> - resolve.modules 指明第三方模块的绝对路径
> - resolve.extensions减少后缀尝试的可能性
> - noParse对完全不需要解析的库进行忽略(不会解析但是仍然会打包到bundle)
> - ignorePlugin完全排除模块
> -  合理使用alias

- 充分利用缓存提升二次构建速度
> -  babel-loader开启缓存
> -  terser-webpack-plugin开启缓存
> -  使用cache-loader或者hard-source-webpack-plugin 注意:thread-loader和cache-loader一起使用的话。顺序为cache-loader-》thread-loader->heavy-loader

- DLL:

 > - 使用DLLPlugin进行分包,使用索引链接对manifest.json引用,让一些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间。

## webpack plugin和loader的区别
loader是文件加载器,能够加载资源文件,并对文件进行处理,比如编译,处理一个文件可以使用多个loader,第一个loader接受的是源文件的内容作为参数,后面的loader接受的是前一个loader的返回值作为参数,最后执行的loader返回该模块的js源码。
plugin功能更强大,非常丰富,让webpack更加灵活,在编译过程中留下一系列生命周期钩子,通过调用钩子函数,来实现在不同的编译结果时对源模块进行处理,