资讯专栏INFORMATION COLUMN

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

qieangel2013 / 1829人阅读

摘要:熟悉了之后,各种新旧项目,大小项目都能用耍的飞起。使用作为文件中的模板安装,记住不是,也不用配置,只需在标签中指定,就可以愉快的使用语法了,比起看起来简洁多了。

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看起来简洁多了。

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"

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82776.html

相关文章

  • 2017-10-13 前端日报

    摘要:前端日报精选设计模式掘金优化向单页应用多路由预渲染指南掘金缓存机制一二三知乎专栏函数式编程在中的应用的学习笔记的学习笔记教程中文可持久化数据结构以及结构分享掘金第期如何准备一次技术面试附一套前端面试题翻译一些新姿势个人文章 2017-10-13 前端日报 精选 JavaScript设计模式 - 掘金优化向:单页应用多路由预渲染指南 - 掘金HTTP 缓存机制一二三 - 知乎专栏函数式编...

    go4it 评论0 收藏0
  • webpack学习心得

    摘要:学习心得出于对的好奇,决定要去学习门技术,提升自己。安装命令行输入回车,全局安装命令行输入回车输出版本号,表示安装成功。进入到我们的项目中,我创建的项目为,在这个项目下创建配置项,命令行输入一路回车。 webpack学习心得 出于对webpack的好奇,决定要去学习门技术,提升自己。 什么是webpack? webpack是德国开发者开发的模块加载器兼打包工具,在webpack中,...

    刘永祥 评论0 收藏0
  • webpack学习心得

    摘要:学习心得出于对的好奇,决定要去学习门技术,提升自己。安装命令行输入回车,全局安装命令行输入回车输出版本号,表示安装成功。进入到我们的项目中,我创建的项目为,在这个项目下创建配置项,命令行输入一路回车。 webpack学习心得 出于对webpack的好奇,决定要去学习门技术,提升自己。 什么是webpack? webpack是德国开发者开发的模块加载器兼打包工具,在webpack中,...

    only_do 评论0 收藏0
  • 搭建基于react项目心得

    摘要:在项目开始之前,不能心急立刻去搭建,需要设定几个步骤来开展,接下来大概的说一下我从技术选型到项目前端搭建好的整个生命周期。开发该项目的底层的内容远不止这些,但由于公司制度规定,只能大概的阐述了在从接手到选型到搭建完毕这到的过程的做法和思考。 前段时间部门要基于一个系统的基础上开发一个管理平台,于是我接手了该平台的重活,因为上一个平台我用了vue搭建,所以这次想用react来搭建。在项目...

    Barrior 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<