webpack在前端项目中使用心得一二

webpack做文件兼并

运用构建东西异常常常使用一个功用就是兼并js和css文件,gulp和grunt都是编写响应的使命来完成,转到webpack倏忽懵逼了,简朴的项目怎么做文件兼并呢?实在只需把多个js文件同时引入到main.js(进口文件)中即可,css借助extract-text-webpack-plugin搞定。

不管是简朴的纯展现页面照样庞杂的单页或多页面,webpack差不多能够完全庖代gulp、grunt了,应用file、scss、pug、babel等种种loader处置惩罚种种需求比grunt那种编写使命型的设置轻易太多。

webpack异常智能,屡次引入雷同模块,终究打包后只会包括一次。假如你不想打包某个模块,在webpack.config.js里设置externals即可。关于css模块,externals是无效的,js里不引入,直接在html里放link就好了,不要堕入webpack的魔障。关于一些老旧的jq插件,能够设置providePlugin或运用expose-loader,用法就自行google了。熟习了以后,种种新旧项目,大小项目都能用webpack耍的飞起。

// webpack.config.js
// ...

externals: {
    'vue': 'Vue',
    'jquery': 'jQuery',
},

webpack-dev-server跨域设置

开辟的时刻常常有跨域需求,前端跨域要领虽然许多,然则只是为了开辟时用用,觉得没一个好用的。应用webpack-dev-server能够轻松处理开辟时跨域题目,devServer启动了一个node服务器帮你代办要求,细致设置请看proxy,这个设置是将一切以/api开首的路由映射到xxx.com,target记得带上协定名哦(http://)。pathRewrite就是将/api/a途径重写为/a。固然你也能够设置为/转发要求,如许静态资本也能够在localhost下要求到了。跨域的条件是服务器上设置了’Access-Control-Allow-Origin:*’,开辟时服务器端平常都设置了。

// webpack.config.js
// ...

devServer: {
    port: 8888,
    historyApiFallback: true,
    stats: 'minimal',  // 输入精简信息
    overlay: true, // 将毛病显现在html之上
    proxy: {
        '/api': {
            target: 'http://xxx.com',
            secure: false,
            changeOrigin: true,
            // pathRewrite: {'^/api': ''},
        }
    }
},

webpack-dev-server热更新失效

自从用了webpack-dev-server,我的f5键长舒一口气,不过有时刻遇到webpack-dev-server热更新回失效,平常是设置出了题目。只需在pulugins里增加HotModule插件,devServer不要设置hot:true了,虽然文档里写的是设置hot:true开启热更新,然则我试过设置hot热更新就失效了,不解!

// webpack.config.js
// ...

plugins: [
        new webpack.HotModuleReplacementPlugin(), // 热加载
]

2017.9.30更新:
webpack文档里写的是命令行加上 -hot 启用热更新形式,不必手动加hrm plugin。
运用extract-text-webpack-plugin和html模版(比方:art-template)时,修正html和css不会触发烧更新,只要js更改能够触发。由于这些loader没有完成hmr相干api,能够经由过程装置css-hot-loader等来hack
有个轻便要领,设置devServer:watchContentBase: true,开启watch形式,文件有修改就会触发自动革新,虽然机能稍差。

运用pug(jade)作为vue文件中的html模板

npm装置pug,记着不是pug-loader,也不必设置vue-loader,只需在template标签中指定lang=pug,就能够兴奋的运用pug语法了,比起html看起来简约多了。

<template lang="pug">
    header
        .logo
        h1 我是头部
</template>

html-webpack-plugin在多页面中的妙用

之前只用webpack写单页援用,index.html就是个空壳,厥后也有一些纯展现页面,包括多个html文件,也想用webpack,毕竟种种loader太好用了。这时刻就需要好好应用html-webpack-plugin了。直接上一个webpack设置,基于vue-simple的webpack设置做了些修正,同时参考了歪闹大神的webpack多页面教程,应用glod猎取文件名,自动天生html-webpack-plugin设置,so geek!应用pug写html,scss写css,作为一个页面仔,也不那么无聊了,效力也是杠杠滴。

let path = require('path');
let webpack = require('webpack');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let glob = require('glob');

// js名必需与html的fileName对应
let entry = (() => {
    let obj = {};
    getEntry('src/views/pages/*.pug').forEach(fileName => {
        obj[fileName] = './src/js/' + fileName + '.js';
    });
    return obj;
})();

module.exports = {
    entry: entry,
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: 'js/[name].js',
        // chunkFilename: 'js/[name][id].chunk.js', // 大众代码块
    },
    externals: {
        // 'vue': 'Vue',
        // 'jquery': 'jQuery',
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        scss: ExtractTextPlugin.extract({
                            fallback: 'vue-style-loader',
                            use: 'css-loader!sass-loader',
                        }),
                    }
                }
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            // 不要运用options设置url-loader webpack会报错
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader?limit=10000&name=img/[name].[hash:7].[ext]',
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                loader: 'file-loader?limit=10000&name=img/[name].[hash:7].[ext]',
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader!postcss-loader!sass-loader'
                })
            },
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader!postcss-loader'
                })
            },
            {
                test: /\.html$/,
                loader: 'html-loader?attrs=img:src img:data-src'
            },
            {
                test: /\.pug$/,
                loader: 'pug-loader'
            },
        ]
    },
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {}
    },
    devServer: {
        port: 8888,
        historyApiFallback: true,
        stats: 'minimal',  // 输入精简信息
        overlay: true, // 将毛病显现在html之上
        proxy: {
            '/api': {
                target: 'http://localhost:9999',
                secure: false,
                changeOrigin: true,
                // pathRewrite: {'^/api': ''},
            }
        }
    },
    performance: {
        hints: false
    },
    devtool: '#eval-source-map',
    plugins: [
        new webpack.HotModuleReplacementPlugin(), // 热加载

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

        new ExtractTextPlugin('css/[name].css'), //零丁运用link标签加载css并设置途径,相干于output设置中的publicPath

    ],
};

if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = '#source-map';
    // http://vue-loader.vuejs.org/en/workflow/production.html
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            sourceMap: true,
            compress: {
                warnings: false
            }
        }),
        new webpack.LoaderOptionsPlugin({
            minimize: true
        })
    ]);
}

// 自动生htmlPlugins
getEntry('src/views/pages/*.pug').forEach(fileName => {
    let conf = {
        filename: fileName + '.html', //天生的html寄存途径,相干于path
        template: 'src/views/pages/' + fileName + '.pug', //html模板途径
        inject: true,
        hash: true,
        minify: {
            removeComments: true,
            minifyJS: true,
        },
        chunks: [fileName],
    };
    module.exports.plugins.push(new HtmlWebpackPlugin(conf));
});

// 猎取文件名函数
function getEntry(viewsPath) {
    let files = glob.sync(viewsPath);
    let entries = [];
    let entry, basename, extname;

    for (let i = 0; i < files.length; i++) {
        entry = files[i];
        extname = path.extname(entry); // 扩展名 eg: .html
        basename = path.basename(entry, extname);  // eg: index
        entries.push(basename);
    }
    return entries;
}

途径 —— alias别号和~的运用

alias:{

'@': path.resolve(__dirname, 'src')

}

import途径中运用别号是一个很好的实践,将@指向src,我们import的时刻以@/开首,在各层目次里就能用种种../

假如你想在css或html运用@,请在前面加上~通知webpack用require处置惩罚他。

比方在是scss里导入其他node_modules里的css文件 @import “~swiper/dist/css/style.css”

比方在是scss里导入其他src下的css文件 @import “~@/css/mixin.css”

    原文作者:wind5o
    原文地址: https://segmentfault.com/a/1190000009243487
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞