亲手搭建vue项目的过程--Module build failed: Unknown word,无法读取css文件
执行webpack-dev-server的时候就报错了,报错如下:ERROR in ./src/components/app.vue?vue&type=style&index=0&id=6c0a0fc1&scoped=true&lang=css& (./node_modules/css-loader/dist/cjs.js!./node_module
执行webpack-dev-server的时候就报错了,报错如下:
ERROR in ./src/components/app.vue?vue&type=style&index=0&id=6c0a0fc1&scoped=true&lang=css& (./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/style-loader/dist/cjs.js!./node_modules/vue-loader/lib??vue-loader-options!./src/components/app.vue?vue&type=style&index=0&id=6c0a0fc1&scoped=true&lang=css&)
Module build failed (from ./node_modules/vue-loader/lib/loaders/stylePostLoader.js):
CssSyntaxError: D:\sources\vue-webpack\src\components\app.vue:1:1: Unknown word
at Input.error (D:\sources\vue-webpack\node_modules\postcss\lib\input.js:130:16)
at Parser.unknownWord (D:\sources\vue-webpack\node_modules\postcss\lib\parser.js:563:22)
at Parser.other (D:\sources\vue-webpack\node_modules\postcss\lib\parser.js:168:12)
at Parser.parse (D:\sources\vue-webpack\node_modules\postcss\lib\parser.js:77:16)
at parse (D:\sources\vue-webpack\node_modules\postcss\lib\parse.js:17:12)
at new LazyResult (D:\sources\vue-webpack\node_modules\postcss\lib\lazy-result.js:60:16)
at Processor.<anonymous> (D:\sources\vue-webpack\node_modules\postcss\lib\processor.js:138:12)
at Processor.process (D:\sources\vue-webpack\node_modules\postcss\lib\processor.js:117:23)
at doCompileStyle (D:\sources\vue-webpack\node_modules\@vue\component-compiler-utils\dist\compileStyle.js:45:35)
at compileStyle (D:\sources\vue-webpack\node_modules\@vue\component-compiler-utils\dist\compileStyle.js:11:12)
at Object.module.exports (D:\sources\vue-webpack\node_modules\vue-loader\lib\loaders\stylePostLoader.js:9:33)
@ ./src/components/app.vue?vue&type=style&index=0&id=6c0a0fc1&scoped=true&lang=css& 1:0-297 1:313-316 1:318-612 1:318-612
@ ./src/components/app.vue
@ ./src/app.js
这个由于是loader配置由问题,加载css,需要使用css-loader,style-loader,loader加载是有先后顺序的,我最开始将css-loader写在了style-loader之前的,所以会报这个错误,将css-loader写在style-loader之前就没有问题了。
我们来看看css-loader和style-loader的作用。
官网文档(css-loader):
The css-loader
interprets @import
and url()
like import/require()
and will resolve them.
toString
你也可以直接将 css-loader 的结果作为字符串使用,例如 Angular 的组件样式。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['to-string-loader', 'css-loader'],
},
],
},
};
或者
const css = require('./test.css').toString();
console.log(css); // {String}
如果有 SourceMap,它们也将包含在字符串结果中。
如果由于某种原因,你需要将 CSS 提取为纯粹的字符串资源 (即不包含在 JS 模块中), 则可能需要查看 extract-loader。 例如,当你需要将 CSS 作为字符串进行后处理时,这很有用。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'handlebars-loader', // handlebars loader expects raw resource string
'extract-loader',
'css-loader',
],
},
],
},
};
选项
名称
类型
默认值
描述
{Boolean|Function}
true
启用/禁用 url()
处理
{Boolean\/Function}
true
启用/禁用 @import 处理
{Boolean\/Function}
false
启用/禁用 CSS 模块和设置模式
{String}
[hash:base64]
配置生成资源的标识符名称
{String}
undefined
Allow to redefine basic loader context for local ident name
{String}
undefined
Allow to add custom hash to generate more unique classes
{Function}
undefined
Configure the function to generate classname based on a different schema
{Boolean}
false
启用/禁用 sourcemap
{Boolean|String}
false
以驼峰式命名导出类名
{Number}
0
在 css-loader 前应用的 loader 的数量
{Boolean}
false
Export only locals
url
类型:Boolean|Function
默认:true
Control url()
resolving. Absolute URLs and root-relative URLs are not resolving.
Examples resolutions:
url(image.png) => require('./image.png')
url('image.png') => require('./image.png')
url(./image.png) => require('./image.png')
url('./image.png') => require('./image.png')
url('http://dontwritehorriblecode.com/2112.png') => require('http://dontwritehorriblecode.com/2112.png')
image-set(url('image2x.png') 1x, url('image1x.png') 2x) => require('./image1x.png') and require('./image2x.png')
To import assets from a node_modules
path (include resolve.modules
) and for alias
, prefix it with a ~
:
url(~module/image.png) => require('module/image.png')
url('~module/image.png') => require('module/image.png')
url(~aliasDirectory/image.png) => require('otherDirectory/image.png')
Boolean
Enable/disable url()
resolving.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
url: true,
},
},
],
},
};
Function
Allow to filter url()
. All filtered url()
will not be resolved (left in the code as they were written).
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
url: (url, resourcePath) => {
// resourcePath - path to css file
// `url()` with `img.png` stay untouched
return url.includes('img.png');
},
},
},
],
},
};
import
类型:Boolean
默认:true
Control @import
resolving. Absolute urls in @import
will be moved in runtime code.
Examples resolutions:
@import 'style.css' => require('./style.css')
@import url(style.css) => require('./style.css')
@import url('style.css') => require('./style.css')
@import './style.css' => require('./style.css')
@import url(./style.css) => require('./style.css')
@import url('./style.css') => require('./style.css')
@import url('http://dontwritehorriblecode.com/style.css') => @import url('http://dontwritehorriblecode.com/style.css') in runtime
To import styles from a node_modules
path (include resolve.modules
) and for alias
, prefix it with a ~
:
@import url(~module/style.css) => require('module/style.css')
@import url('~module/style.css') => require('module/style.css')
@import url(~aliasDirectory/style.css) => require('otherDirectory/style.css')
Boolean
Enable/disable @import
resolving.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
import: true,
},
},
],
},
};
Function
Allow to filter @import
. All filtered @import
will not be resolved (left in the code as they were written).
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
import: (parsedImport, resourcePath) => {
// parsedImport.url - url of `@import`
// parsedImport.media - media query of `@import`
// resourcePath - path to css file
// `@import` with `style.css` stay untouched
return parsedImport.url.includes('style.css');
},
},
},
],
},
};
modules
modules
" class="icon-link" href="#modules">
类型:Boolean|String
默认:false
The modules
option enables/disables the CSS Modules spec and setup basic behaviour.
Name
Type
Description
true
{Boolean}
Enables local scoped CSS by default (use local mode by default)
false
{Boolean}
Disable the CSS Modules spec, all CSS Modules features (like @value
, :local
, :global
and composes
) will not work
'local'
{String}
Enables local scoped CSS by default (same as true
value)
'global'
{String}
Enables global scoped CSS by default
Using false
value increase performance because we avoid parsing CSS Modules features, it will be useful for developers who use vanilla css or use other technologies.
You can read about modes below.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
};
Scope
Using local
value requires you to specify :global
classes. Using global
value requires you to specify :local
classes.
You can find more information here.
Styles can be locally scoped to avoid globally scoping styles.
语法 :local(.className)
可以被用来在局部作用域中声明 className
。局部的作用域标识符会以模块形式暴露出去。
使用 :local
(无括号)可以为此选择器启用局部模式。 :global(.className)
可以用来声明一个明确的全局选择器。 使用 :global
(无括号)可以将此选择器切换至全局模式。
loader 会用唯一的标识符(identifier)来替换局部选择器。所选择的唯一标识符以模块形式暴露出去。
:local(.className) {
background: red;
}
:local .className {
color: green;
}
:local(.className .subClass) {
color: green;
}
:local .className .subClass :global(.global-class-name) {
color: blue;
}
._23_aKvs-b8bW2Vg3fwHozO {
background: red;
}
._23_aKvs-b8bW2Vg3fwHozO {
color: green;
}
._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 {
color: green;
}
._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 .global-class-name {
color: blue;
}
ℹ️ 主要信息: 标识符被导出
exports.locals = {
className: '_23_aKvs-b8bW2Vg3fwHozO',
subClass: '_13LGdX8RMStbBE9w-t0gZ1',
};
建议局部选择器使用驼峰式。它们在导入 JS 模块中更容易使用。
你可以使用 :local(#someId)
,但不推荐这种用法。推荐使用 class 代替 id。
Composing
当声明一个局部类名时,你可以与另一个局部类名组合为一个局部类。
:local(.className) {
background: red;
color: yellow;
}
:local(.subClass) {
composes: className;
background: blue;
}
这不会导致 CSS 本身的任何更改,而是导出多个类名。
exports.locals = {
className: '_23_aKvs-b8bW2Vg3fwHozO',
subClass: '_13LGdX8RMStbBE9w-t0gZ1 _23_aKvs-b8bW2Vg3fwHozO',
};
._23_aKvs-b8bW2Vg3fwHozO {
background: red;
color: yellow;
}
._13LGdX8RMStbBE9w-t0gZ1 {
background: blue;
}
Importing
从其他模块导入局部类名。
:local(.continueButton) {
composes: button from 'library/button.css';
background: red;
}
:local(.nameEdit) {
composes: edit highlight from './edit.css';
background: red;
}
要从多个模块导入,请使用多个 composes:
规则。
:local(.className) {
composes: edit hightlight from './edit.css';
composes: button from 'module/button.css';
composes: classFromThisModule;
background: red;
}
localIdentName
类型:String
默认:[hash:base64]
You can configure the generated ident with the localIdentName
query parameter. See loader-utils's documentation for more information on options.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
},
},
],
},
};
context
类型:String
默认:undefined
Allow to redefine basic loader context for local ident name. By default we use rootContext
of loader.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
context: path.resolve(__dirname, 'context'),
},
},
],
},
};
hashPrefix
类型:String
默认:undefined
Allow to add custom hash to generate more unique classes.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
hashPrefix: 'hash',
},
},
],
},
};
getLocalIdent
类型:Function
默认:undefined
You can also specify the absolute path to your custom getLocalIdent
function to generate classname based on a different schema. By default we use built-in function to generate a classname.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
getLocalIdent: (context, localIdentName, localName, options) => {
return 'whatever_random_class_name';
},
},
},
],
},
};
sourceMap
类型:Boolean
默认:false
设置 sourceMap
选项查询参数来引入 source map。
例如,mini-css-extract-plugin
能够处理它们。
默认情况下不启用它们,因为它们会导致运行时的额外开销,并增加了 bundle 大小 (JS source map 不会)。此外,相对路径是错误的,你需要使用包含服务器 URL 的绝对公用路径。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
sourceMap: true,
},
},
],
},
};
camelCase
类型:Boolean|String
默认:false
默认情况下,导出 JSON 键值对形式的类名。如果想要驼峰化(camelize)类名(有助于在 JS 中使用),通过设置 css-loader 的查询参数 camelCase
即可实现。
名称
类型
描述
false
{Boolean}
Class names will be camelized, the original class name will not to be removed from the locals
true
{Boolean}
类名将被骆驼化
'dashes'
{String}
只有类名中的破折号将被骆驼化
'only'
{String}
在 0.27.1
中加入。类名将被骆驼化,初始类名将从局部移除
'dashesOnly'
{String}
在 0.27.1
中加入。类名中的破折号将被骆驼化,初始类名将从局部移除
file.css
.class-name {
}
file.js
import { className } from 'file.css';
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
camelCase: true,
},
},
],
},
};
importLoaders
类型:Number
默认:0
查询参数 importLoaders
,用于配置「css-loader
作用于 @import
的资源之前」有多少个 loader。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2, // 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
},
},
'postcss-loader',
'sass-loader',
],
},
],
},
};
在模块系统(即 webpack)支持原始 loader 匹配后,此功能可能在将来会发生变化。
exportOnlyLocals
类型:Boolean
默认:false
Export only locals (useful when you use css modules). For pre-rendering with mini-css-extract-plugin
you should use this option instead of style-loader!css-loader
in the pre-rendering bundle. It doesn't embed CSS but only exports the identifier mappings.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
exportOnlyLocals: true,
},
},
],
},
};
style-loader:
建议将 style-loader
与 css-loader
结合使用
component.js
import style from './file.css';
webpack.config.js
{
module: {
rules: [
{
test: /\.css$/,
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
},
];
}
}
###
在使用局部作用域 CSS 时,模块导出生成的(局部)标识符(identifier)。
component.js
import style from './file.css';
style.className === 'z849f98ca812';
Url
也可以添加一个URL <link href="path/to/file.css" rel="stylesheet">
,而不是用带有 <style></style>
标签的内联 CSS {String}
。
import url from 'file.css';
webpack.config.js
{
module: {
rules: [
{
test: /\.css$/,
use: [{ loader: 'style-loader/url' }, { loader: 'file-loader' }],
},
];
}
}
<link rel="stylesheet" href="path/to/file.css" />
ℹ️ 使用
url
引用的 Source map 和资源:当 style-loader 与{ options: { sourceMap: true } }
选项一起使用时,CSS 模块将生成为Blob
,因此相对路径无法正常工作(他们将相对于chrome:blob
或chrome:devtools
)。为了使资源保持正确的路径,必须设置 webpack 配置中的output.publicPath
属性,以便生成绝对路径。或者,你可以启用上面提到的convertToAbsoluteUrls
选项。
可选的(Useable)
The style-loader
injects the styles lazily making them useable on-demand via style.use()
/ style.unuse()
按照惯例,引用计数器 API(Reference Counter API)
应关联到 .useable.css
,而 .css
的载入,应该使用基本的 style-loader
用法(类似于其他文件类型,例如 .useable.less
和 .less
)。
webpack.config.js
{
module: {
rules: [
{
test: /\.css$/,
exclude: /\.useable\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
],
},
{
test: /\.useable\.css$/,
use: [
{
loader: "style-loader/useable"
},
{ loader: "css-loader" },
],
},
],
},
}
引用计数器 API(reference counter API)
component.js
import style from './file.css';
style.use(); // = style.ref();
style.unuse(); // = style.unref();
样式不会添加在 import/require()
上,而是在调用 use
/ref
时添加。如果 unuse
/unref
与 use
/ref
一样频繁地被调用,那么样式将从页面中删除。
⚠️ 当
unuse
/unref
比use
/ref
调用频繁的时候,产生的行为是不确定的。所以不要这样做。
选项
名称
类型
默认值
描述
hmr
{Boolean}
true
Enable/disable Hot Module Replacement (HMR), if disabled no HMR Code will be added (good for non local development/production)
base
{Number}
true
设置模块 ID 基础 (DLLPlugin)
attrs
{Object}
{}
添加自定义 attrs 到 <style></style>
transform
{Function}
false
转换/条件加载 CSS,通过传递转换/条件函数
insertAt
{String|Object}
bottom
在给定位置处插入 <style></style>
insertInto
{String}
<head>
给定位置中插入 <style></style>
singleton
{Boolean}
undefined
Reuses a single <style></style>
element, instead of adding/removing individual elements for each required module.
sourceMap
{Boolean}
false
启用/禁用 Sourcemap
convertToAbsoluteUrls
{Boolean}
false
启用 source map 后,将相对 URL 转换为绝对 URL
hmr
Enable/disable Hot Module Replacement (HMR), if disabled no HMR Code will be added. This could be used for non local development and production.
webpack.config.js
{
loader: 'style-loader',
options: {
hmr: false
}
}
base
当使用一个或多个 DllPlugin 时,此设置主要用作 css 冲突 的修补方案。base
可以防止 app 的 css(或 DllPlugin2 的 css)覆盖 DllPlugin1 的 css,方法是指定一个 css 模块的 id 大于 DllPlugin1 的范围,例如:
webpack.dll1.config.js
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
webpack.dll2.config.js
{
test: /\.css$/,
use: [
{ loader: 'style-loader', options: { base: 1000 } },
'css-loader'
]
}
webpack.app.config.js
{
test: /\.css$/,
use: [
{ loader: 'style-loader', options: { base: 2000 } },
'css-loader'
]
}
attrs
如果已定义,style-loader 将把属性值附加在 <style>
/ <link>
元素上。
component.js
import style from './file.css';
webpack.config.js
{
test: /\.css$/,
use: [
{ loader: 'style-loader', options: { attrs: { id: 'id' } } }
{ loader: 'css-loader' }
]
}
<style id="id"></style>
Url
component.js
import link from './file.css';
webpack.config.js
{
test: /\.css$/,
use: [
{ loader: 'style-loader/url', options: { attrs: { id: 'id' } } }
{ loader: 'file-loader' }
]
}
transform
transform
是一个函数,可以在通过 style-loader 加载到页面之前修改 css。 该函数将在即将加载的 css 上调用,函数的返回值将被加载到页面,而不是原始的 css 中。 如果 transform
函数的返回值是 falsy 值,那么 css 根本就不会加载到页面中。
⚠️ In case you are using ES Module syntax in
tranform.js
then, you need to transpile it or otherwise it will throw an{Error}
.
webpack.config.js
{
loader: 'style-loader',
options: {
transform: 'path/to/transform.js'
}
}
transform.js
module.exports = function(css) {
// Here we can change the original css
const transformed = css.replace('.classNameA', '.classNameB');
return transformed;
};
Conditional
webpack.config.js
{
loader: 'style-loader',
options: {
transform: 'path/to/conditional.js'
}
}
conditional.js
module.exports = function(css) {
// 如果条件匹配则加载[和转换] CSS
if (css.includes('something I want to check')) {
return css;
}
// 如果返回 falsy 值,则不会加载 CSS
return false;
};
insertAt
默认情况下,style-loader 将 <style>
元素附加到样式目标(style target)的末尾,即页面的 <head>
标签,也可以是由 insertInto
指定其他标签。这将导致 loader 创建的 CSS 优先于目标中已经存在的 CSS。要在目标的起始处插入 style 元素,请将此查询参数(query parameter)设置为 'top',例如
webpack.config.js
{
loader: 'style-loader',
options: {
insertAt: 'top'
}
}
A new <style>
element can be inserted before a specific element by passing an object, e.g.
webpack.config.js
{
loader: 'style-loader',
options: {
insertAt: {
before: '#id'
}
}
}
insertInto
默认情况下,样式加载器将 <style>
元素插入到页面的 <head>
标签中。如果要将标签插入到其他位置,可以在这里为该元素指定 CSS 选择器。如果你想要插入到 IFrame 中,请确保你具有足够的访问权限,样式将被注入到内容文档的 head 中。
You can also pass function to override default behavior and insert styles in your container, e.g
webpack.config.js
{
loader: 'style-loader',
options: {
insertInto: () => document.querySelector("#root"),
}
}
通过使用函数,可以将样式插入到 ShadowRoot 中,例如
webpack.config.js
{
loader: 'style-loader',
options: {
insertInto: () => document.querySelector("#root").shadowRoot,
}
}
singleton
如果已定义,则 style-loader 将重用单个 <style></style>
元素,而不是为每个所需的模块添加/删除单个元素。
ℹ️ 默认情况下启用此选项,IE9 对页面上允许的 style 标签数量有严格的限制。你可以使用 singleton 选项来启用或禁用它。
webpack.config.js
{
loader: 'style-loader',
options: {
singleton: true
}
}
sourceMap
启用/禁用 source map 加载
webpack.config.js
{
loader: 'style-loader',
options: {
sourceMap: true
}
}
convertToAbsoluteUrls
如果 convertToAbsoluteUrls 和 sourceMaps 都启用,那么相对 url 将在 css 注入页面之前,被转换为绝对 url。这解决了在启用 source map 时,相对资源无法加载的问题。你可以使用 convertToAbsoluteUrls 选项启用它。
webpack.config.js
{
loader: 'style-loader',
options: {
sourceMap: true,
convertToAbsoluteUrls: true
}
}
更多推荐
所有评论(0)