Bre*_*aut 58 javascript css build webpack css-preprocessor
我有:
我希望将这些指定为两个单独的输入并具有两个单独的输出(可能通过extract-text-webpack-plugin).Webpack有所有适当的插件/加载器来进行编译,但它似乎不喜欢分离.
我已经看到人们需要直接从JS获取LESS文件的例子,例如require('./app.less');
,除了告诉webpack将这些文件包含在bundle中之外别无他法.这允许你只有一个入口点,但这对我来说似乎非常不对 - 为什么我的JS中的LESS与我的JS代码无关时需要LESS?
我尝试使用多个入口点,将条目JS和主LESS文件都放入其中,但是当使用多个入口点时,webpack会生成一个在加载时不执行JS的包 - 它将所有内容捆绑在一起,但不知道什么应该在启动时执行.
我只是使用webpack错了吗?我应该为这些单独的模块运行单独的webpack实例吗?如果我不打算将它们混合到我的JS中,我是否应该将webpack用于非JS资产?
Bre*_*non 23
如果我不打算将它们混合到我的JS中,我是否应该将webpack用于非JS资产?
也许不吧.Webpack绝对是以js为中心的,隐含的假设是你正在构建的是一个js应用程序.它的实现require()
允许您将所有内容视为一个模块(包括Sass/LESS partials,JSON,几乎任何东西),并自动为您进行依赖管理(require
捆绑的所有内容,而不是其他内容).
当我的JS代码与我的JS代码无关时,为什么我需要在JS中使用LESS?
人们这样做是因为他们用js定义了他们的应用程序(例如React组件,Backbone View).应用程序的那一块有CSS随之而来.取决于一些单独构建的外部CSS资源,而不是直接从js模块引用,它是脆弱的,难以使用,并且可能导致样式过时等等.Webpack鼓励你保持所有模块化,所以你有一个CSS (Sass,无论如何)部分与js组件相关,而js组件require()
则使依赖性变得清晰(对于您和构建工具,它永远不会构建您不需要的样式).
我不知道你是否可以使用webpack自己捆绑CSS(当CSS文件没有从任何js引用时).我确定你可以用插件等连接一些东西,但不确定它是否可以开箱即用.如果您确实从js引用CSS文件,您可以轻松地将CSS捆绑到带有Extract Text插件的单独文件中,如您所述.
lfe*_*445 16
webpack 团队建议在提取文本插件上使用 mini-css-extract
此解决方案允许您创建一个单独的块,仅包含您的 css 条目:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
function recursiveIssuer(m) {
if (m.issuer) {
return recursiveIssuer(m.issuer);
} else if (m.name) {
return m.name;
} else {
return false;
}
}
module.exports = {
entry: {
foo: path.resolve(__dirname, 'src/foo'),
bar: path.resolve(__dirname, 'src/bar'),
},
optimization: {
splitChunks: {
cacheGroups: {
fooStyles: {
name: 'foo',
test: (m, c, entry = 'foo') =>
m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true,
},
barStyles: {
name: 'bar',
test: (m, c, entry = 'bar') =>
m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
};
Run Code Online (Sandbox Code Playgroud)
这是一个使用我个人项目中的多个条目的更人为的示例:
const ManifestPlugin = require('webpack-manifest-plugin')
const webpack = require('webpack')
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const VENDOR = path.join(__dirname, 'node_modules')
const LOCAL_JS = path.join(__dirname, 'app/assets/js')
const LOCAL_SCSS = path.join(__dirname, 'app/assets/scss')
const BUILD_DIR = path.join(__dirname, 'public/dist')
const EXTERNAL = path.join(__dirname, 'public/external')
function recursiveIssuer(m) {
if (m.issuer) {
return recursiveIssuer(m.issuer);
} else if (m.name) {
return m.name;
} else {
return false;
}
}
module.exports = {
entry: {
vendor: [
`${VENDOR}/jquery/dist/jquery.js`,
`${VENDOR}/codemirror/lib/codemirror.js`,
`${VENDOR}/codemirror/mode/javascript/javascript.js`,
`${VENDOR}/codemirror/mode/yaml/yaml.js`,
`${VENDOR}/zeroclipboard/dist/ZeroClipboard.js`,
],
app: [
`${LOCAL_JS}/utils.js`,
`${LOCAL_JS}/editor.js`,
`${LOCAL_JS}/clipboard.js`,
`${LOCAL_JS}/fixtures.js`,
`${LOCAL_JS}/ui.js`,
`${LOCAL_JS}/data.js`,
`${LOCAL_JS}/application.js`,
`${LOCAL_JS}/google.js`
],
'appStyles': [
`${EXTERNAL}/montserrat.css`,
`${EXTERNAL}/icons.css`,
`${VENDOR}/purecss/pure-min.css`,
`${VENDOR}/purecss/grids-core-min.css`,
`${VENDOR}/purecss/grids-responsive-min.css`,
`${VENDOR}/codemirror/lib/codemirror.css`,
`${VENDOR}/codemirror/theme/monokai.css`,
]
},
optimization: {
splitChunks: {
cacheGroups: {
appStyles: {
name: 'appStyles',
test: (m, c, entry = 'appStyles') =>
m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true,
},
},
},
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [ 'script-loader'],
},
{
test: /\.(scss|css)$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
},
],
},
mode: 'development',
resolve: {
extensions: ['.js', '.css', '.scss']
},
output: {
path: BUILD_DIR,
filename: "[name].[chunkhash].js",
},
plugins: [
new ManifestPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css'
}),
]
};
Run Code Online (Sandbox Code Playgroud)
我意识到这种方法不是很模块化,但它应该为您提供构建基础,并且是在您不希望混合使用 javascript 和 css 的项目中采用 webpack 的绝佳策略。
这种方法的缺点是 css-loader 仍然会生成一个额外的 javascript 文件(无论您是否选择使用它),这应该会在 webpack 5 中修复。
如果我不打算将它们混合到我的 JS 中,我什至应该将 webpack 用于非 JS 资产吗?
我认为这没有任何问题,但最终取决于您对管理多个构建系统的容忍度。对我来说这感觉有点矫枉过正,所以我更喜欢留在 webpack 生态系统中。
有关上述策略的更多信息,请参阅https://github.com/webpack-contrib/mini-css-extract-plugin#extracting-css-based-on-entry
bdm*_*son 15
可以在不使用require('main/less)
任何JS的情况下生成单独的CSS包,但正如Brendan在其答案的第一部分中所指出的,Webpack不是为全局CSS包而设计的,而是模块化JS,但是有几个选项.
第一种是为main.less添加一个额外的入口点,然后使用Extract Text插件创建CSS包:
var webpack = require('webpack'),
ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: {
home: [
'js/common',
'js/homepage'
],
style: [
'styles/main.less'
]
},
output: {
path: 'dist',
filename: "[name].min.js"
},
resolve: {
extensions: ["", ".js"]
},
module: {
loaders: [{
test: /\.less$/,
loader: ExtractTextPlugin.extract("style", "css", "less")
}]
},
plugins: [
new ExtractTextPlugin("[name].min.css", {
allChunks: true
})
]
};
Run Code Online (Sandbox Code Playgroud)
这个方法的问题是你还生成了一个不需要的JS文件以及bundle,在这个例子中:style.js
它只是一个空的Webpack模块.
另一种选择是将main less文件添加到现有的Webpack入口点:
var webpack = require('webpack'),
ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: {
home: [
'js/common',
'js/homepage',
'styles/main.less'
],
},
output: {
path: 'dist',
filename: "[name].min.js"
},
resolve: {
extensions: ["", ".js"]
},
module: {
loaders: [{
test: /\.less$/,
loader: ExtractTextPlugin.extract("style", "css", "less")
}]
},
plugins: [
new ExtractTextPlugin("[name].min.css", {
allChunks: true
})
]
};
Run Code Online (Sandbox Code Playgroud)
如果你只有1个入口点,这是理想的,但如果你有更多,那么你的Webpack配置看起来有点奇怪,因为你必须随意选择添加主要较少文件的入口点.
为了进一步阐明bdmason以前的答案-似乎理想的配置是为每个页面创建JS和CSS包,如下所示:
entry: {
Home: ["./path/to/home.js", "./path/to/home.less"],
About: ["./path/to/about.js", "./path/to/about.less"]
}
Run Code Online (Sandbox Code Playgroud)
然后使用[name]
开关:
output: {
path: "path/to/generated/bundles",
filename: "[name].js"
},
plugins: new ExtractTextPlugin("[name].css")
Run Code Online (Sandbox Code Playgroud)
完整配置-某些附加问题未解决(我们实际上使用的是SASS而不是LESS):
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
require('babel-polyfill');
module.exports = [{
devtool: debug ? "inline-sourcemap" : null,
entry: {
Home: ['babel-polyfill', "./home.js","path/to/HomeRootStyle.scss"],
SearchResults: ['babel-polyfill', "./searchResults.js","path/to/SearchResultsRootStyle.scss"]
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy']
}
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract("style-loader","css-raw-loader!sass-loader")
}
]
},
output: {
path: "./res/generated",
filename: "[name].js"
},
plugins: debug ? [new ExtractTextPlugin("[name].css")] : [
new ExtractTextPlugin("[name].css"),
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
compress:{
warnings: true
}
})
]
}
];
Run Code Online (Sandbox Code Playgroud)
是的,这是可能的,但是就像其他人所说的那样,您将需要其他程序包(请参阅package.json下的devDependencies)。这是我用来编译Bootstrap SCSS-> CSS和Bootstrap JS-> JS的示例代码。
webpack.config.js:
module.exports = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
entry: ['./src/app.js', './src/scss/app.scss'],
output: {
path: path.resolve(__dirname, 'lib/modules/theme/public'),
filename: 'js/bootstrap.js'
},
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'file-loader',
options: {
name: 'css/bootstrap.css',
}
},
{
loader: 'extract-loader'
},
{
loader: 'css-loader?-url'
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
}
]
}
};
Run Code Online (Sandbox Code Playgroud)
其他postcss.config.js文件:
module.exports = {
plugins: {
'autoprefixer': {}
}
}
Run Code Online (Sandbox Code Playgroud)
package.json:
{
"main": "app.js",
"scripts": {
"build": "webpack",
"start": "node app.js"
},
"author": "P'unk Avenue",
"license": "MIT",
"dependencies": {
"bootstrap": "^4.1.3",
},
"devDependencies": {
"autoprefixer": "^9.3.1",
"css-loader": "^1.0.1",
"exports-loader": "^0.7.0",
"extract-loader": "^3.1.0",
"file-loader": "^2.0.0",
"node-sass": "^4.10.0",
"popper.js": "^1.14.6",
"postcss-cli": "^6.0.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.26.1",
"webpack-cli": "^3.1.2"
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅此处的教程:https : //florianbrinkmann.com/en/4240/sass-webpack
就像其他人提到的那样,您可以使用插件。
ExtractTextPlugin
已弃用。
MiniCssExtractPlugin
您可以在 webpack 配置中使用当前推荐的:
module.exports = {
entry: {
home: ['index.js', 'index.less']
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
]
}
Run Code Online (Sandbox Code Playgroud)