详解vue-loader在项目中是如何配置的
什么是vue-loader
这是我入职第三天的故事,在写这篇文章之前,先来看看咱们今天要讲的主角——vue-loader
,你对它了解多少?
这是我今天的回答,确实,vue-loader是webpack的一个loader,用于处理.vue文件。
.vue 文件是一个自定义的文件类型,用类 html 语法描述一个 vue 组件。每个 .vue 文件包含三种类型的*语言块 <template>、<script>和 <style>。
vue-loader 会解析文件,提取每个语言块,如有必要会通过其它 loader 处理(比如<script>默认用babel-loader处理,<style>默认用style-loader处理),最后将他们组装成一个 commonjs 模块,module.exports 出一个 vue.js 组件对象。
vue-loader 支持使用非默认语言,比如 css 预处理器,预编译的 html 模版语言,通过设置语言块的 lang 属性。例如,你可以像下面这样使用 sass 语法编写样式:
<style lang="sass"> /* write sass! */ </style>
知道了什么是vue-loader之后,我们先来创建项目。为了快速地聊聊vue-loader,我在这里推荐用脚手架工具 @vue/cli 来创建一个使用 vue-loader 的项目:
npm install -g @vue/cli vue create hello-world cd hello-world npm run serve
这个过程我可以等等你们,because this might take a while...
当你在浏览器里输入localhost:8080之后,浏览器会友善地渲染出一个welcome to your vue.js app
的欢迎页面。
紧接着,我们需要打开你擅长的编辑器,这里我选用的是vscode,顺手将项目导入进来,你会看到最原始的一个项目工程目录,里面只有一些简单的项目构成,还没有vue-loader的配置文件:
首先,我们需要在项目根目录下面新建一个webpack.config.js
文件,然后开始我们今天的主题。
手动配置css到单独文件
说到提取css文件,我们应该先去terminal终端去安装一下相关的npm包:
npm install extract-text-webpack-plugin --save-dev
先来说个简答的方法,上代码:
// webpack.config.js var extracttextplugin = require("extract-text-webpack-plugin") module.exports = { // other options... module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { extractcss: true } } ] }, plugins: [ new extracttextplugin("style.css") ] }
上述内容将自动处理 *.vue 文件内的 <style> 提取到style.css文件里面,并与大多数预处理器一样开箱即用。
注意这只是提取 *.vue 文件 - 但在 javascript 中导入的 css 仍然需要单独配置。
接下来我们再看看如何手动配置:
// webpack.config.js var extracttextplugin = require("extract-text-webpack-plugin") module.exports = { // other options... module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { css: extracttextplugin.extract({ use: 'css-loader', fallback: 'vue-style-loader' // 这是vue-loader的依赖 }) } } } ] }, plugins: [ new extracttextplugin("style.css") ] }
此举便将所有 vue 组件中的所有已处理的 css 提取到了单个的 css 文件。
如何构建生产环境
生产环境打包,目的只有两个:1.压缩应用代码;2.去除vue.js中的警告。
下面的配置仅供参考:
// webpack.config.js module.exports = { // ... other options plugins: [ new webpack.defineplugin({ 'process.env': { node_env: '"production"' } }), new webpack.optimize.uglifyjsplugin() ] }
当然,如果我们不想在开发过程中使用这些配置,有两种方法可以解决这个问题:
1.使用环境变量动态构建;
例如:const isdev = process.env.node_env==='development'
或者:const isprod = process.env.node_env === 'production'
2.使用两个分开的 webpack 配置文件,一个用于开发环境,一个用于生产环境。把可能共用的配置放到第三个文件中。
借鉴大牛的经验
这里提供一个网上标准的写法,名字叫做vue-hackernews-2.0,这里是传送门:
其*用的配置文件webpack.base.config.js的代码如下:
const path = require('path') const webpack = require('webpack') const extracttextplugin = require('extract-text-webpack-plugin') const friendlyerrorsplugin = require('friendly-errors-webpack-plugin') const { vueloaderplugin } = require('vue-loader') const isprod = process.env.node_env === 'production' module.exports = { devtool: isprod ? false : '#cheap-module-source-map', output: { path: path.resolve(__dirname, '../dist'), publicpath: '/dist/', filename: '[name].[chunkhash].js' }, resolve: { alias: { 'public': path.resolve(__dirname, '../public') } }, module: { noparse: /es6-promise\.js$/, // avoid webpack shimming process rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { compileroptions: { preservewhitespace: false } } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg)$/, loader: 'url-loader', options: { limit: 10000, name: '[name].[ext]?[hash]' } }, { test: /\.styl(us)?$/, use: isprod ? extracttextplugin.extract({ use: [ { loader: 'css-loader', options: { minimize: true } }, 'stylus-loader' ], fallback: 'vue-style-loader' }) : ['vue-style-loader', 'css-loader', 'stylus-loader'] }, ] }, performance: { maxentrypointsize: 300000, hints: isprod ? 'warning' : false }, plugins: isprod ? [ new vueloaderplugin(), new webpack.optimize.uglifyjsplugin({ compress: { warnings: false } }), new webpack.optimize.moduleconcatenationplugin(), new extracttextplugin({ filename: 'common.[chunkhash].css' }) ] : [ new vueloaderplugin(), new friendlyerrorsplugin() ] }
然后看看用于开发环境的webpack.client.config.js的配置是如何写的:
const webpack = require('webpack') const merge = require('webpack-merge') const base = require('./webpack.base.config') const swprecacheplugin = require('sw-precache-webpack-plugin') const vuessrclientplugin = require('vue-server-renderer/client-plugin') const config = merge(base, { entry: { app: './src/entry-client.js' }, resolve: { alias: { 'create-api': './create-api-client.js' } }, plugins: [ // strip dev-only code in vue source new webpack.defineplugin({ 'process.env.node_env': json.stringify(process.env.node_env || 'development'), 'process.env.vue_env': '"client"' }), // extract vendor chunks for better caching new webpack.optimize.commonschunkplugin({ name: 'vendor', minchunks: function (module) { // a module is extracted into the vendor chunk if... return ( // it's inside node_modules /node_modules/.test(module.context) && // and not a css file (due to extract-text-webpack-plugin limitation) !/\.css$/.test(module.request) ) } }), // extract webpack runtime & manifest to avoid vendor chunk hash changing // on every build. new webpack.optimize.commonschunkplugin({ name: 'manifest' }), new vuessrclientplugin() ] }) if (process.env.node_env === 'production') { config.plugins.push( // auto generate service worker new swprecacheplugin({ cacheid: 'vue-hn', filename: 'service-worker.js', minify: true, dontcachebusturlsmatching: /./, staticfileglobsignorepatterns: [/\.map$/, /\.json$/], runtimecaching: [ { urlpattern: '/', handler: 'networkfirst' }, { urlpattern: /\/(top|new|show|ask|jobs)/, handler: 'networkfirst' }, { urlpattern: '/item/:id', handler: 'networkfirst' }, { urlpattern: '/user/:id', handler: 'networkfirst' } ] }) ) } module.exports = config
最后来看看开发环境中的webpack.server.config.js的配置是怎么写的:
const webpack = require('webpack') const merge = require('webpack-merge') const base = require('./webpack.base.config') const nodeexternals = require('webpack-node-externals') const vuessrserverplugin = require('vue-server-renderer/server-plugin') module.exports = merge(base, { target: 'node', devtool: '#source-map', entry: './src/entry-server.js', output: { filename: 'server-bundle.js', librarytarget: 'commonjs2' }, resolve: { alias: { 'create-api': './create-api-server.js' } }, // https://webpack.js.org/configuration/externals/#externals // https://github.com/liady/webpack-node-externals externals: nodeexternals({ // do not externalize css files in case we need to import it from a dep whitelist: /\.css$/ }), plugins: [ new webpack.defineplugin({ 'process.env.node_env': json.stringify(process.env.node_env || 'development'), 'process.env.vue_env': '"server"' }), new vuessrserverplugin() ] })
如何进行代码检验
你可能有疑问,在 .vue 文件中你怎么检验你的代码,因为它不是 javascript。我们假设你使用 eslint (如果你没有使用话,你应该去使用!)。
首先你要去安装eslint-loader:
npm install eslint eslint-loader --save-dev
然后将它应用在pre-loader上:
// webpack.config.js module.exports = { // ... other options module: { rules: [ { enforce: 'pre', test: /\.(js|vue)$/, loader: 'eslint-loader', exclude: /node_modules/ } ] } }
这样你的 .vue 文件会在开发期间每次保存时自动检验。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
详解vue-loader在项目中是如何配置的
-
babel在项目中是如何使用的?
-
关于express-session配置项在node.js中的详解
-
关于express-session配置项在node.js中的详解
-
在高并发项目中,缓存,opcode代码块,服务器、数据库的配置,是在什么时候做的呢?
-
ASP.NET Core类库项目中如何实现读取配置文件的详解
-
在Linux下VMware虚拟机中如何配置静态IP的详解(图)
-
ASP.NET Core类库项目中如何实现读取配置文件的详解
-
在Linux下VMware虚拟机中如何配置静态IP的详解(图)
-
在PHP中模式修正符有哪些?是如何使用的?(附详解)