Могу ли я использовать webpack для генерации CSS и JS отдельно?
У меня есть:
- Файлы JS, которые я хочу связать.
- МЕНЬШИЕ файлы, которые я хочу скомпилировать до CSS (разрешая @imports в один комплект).
Я надеялся указать их как два отдельных входа и иметь два отдельных выхода (вероятно, через extract-text-webpack-plugin). У Webpack есть все необходимые плагины/загрузчики для компиляции, но это не похоже на разделение.
Я видел примеры людей, которым требуются файлы LESS непосредственно из JS, такие как require('./app.less');
, ни по какой другой причине, кроме как сказать webpack о включении этих файлов в комплект. Это позволяет вам иметь только одну точку входа, но мне кажется, что это неправильно для меня - зачем мне требовать МЕНЬШЕ в моем JS, когда это не имеет никакого отношения к моему JS-коду?
Я попытался использовать несколько точек входа, передав как входной JS, так и основной LESS файл, но при использовании нескольких точек входа webpack генерирует пакет, который не запускает JS при загрузке - он связывает все это, но doesn Не знаю, что должно быть выполнено при запуске.
Я просто использую webpack неправильно? Должен ли я запускать отдельные экземпляры webpack для этих отдельных модулей? Должен ли я использовать webpack для активов, отличных от JS, если я не собираюсь смешивать их с JS?
Ответы
Ответ 1
Должен ли я использовать webpack для активов, отличных от JS, если я не собираюсь смешивать их с JS?
Может и нет. Webpack определенно js-centric, с неявным предположением, что то, что вы строите, является js-приложением. Его реализация require()
позволяет рассматривать все как модуль (в том числе частичные Sass/LESS, JSON, почти все) и автоматически управляет вашим управлением зависимостями (все, что вы require
в комплекте, и ничего больше).
зачем мне требовать МЕНЬШЕ в моем JS, когда это не имеет никакого отношения к моему JS-коду?
Люди делают это, потому что они определяют часть своего приложения (например, компонент React, Backbone View) с js. В этой части приложения есть CSS, который идет с ним. В зависимости от некоторого внешнего ресурса CSS, который создается отдельно, а не напрямую ссылается на модуль js, он хрупкий, сложнее работать и может привести к устареванию стилей и т.д. Webpack рекомендует вам хранить все модульные, поэтому у вас есть CSS (Sass, что бы то ни было), частично связанный с этим компонентом js, и компонент js require()
, чтобы сделать зависимость понятной (вам и инструменту построения, который никогда не создает стили, которые вам не нужны).
Я не знаю, можно ли использовать webpack для объединения CSS самостоятельно (когда файлы CSS не ссылаются ни на какие js). Я уверен, что вы можете подключить что-то с помощью плагинов и т.д., Но не уверены, что это возможно из коробки. Если вы ссылаетесь на файлы CSS из js, вы можете легко связать CSS в отдельный файл с помощью модуля Extract Text, как вы говорите.
Ответ 2
Отдельный набор CSS может быть сгенерирован без использования require('main/less)
в любом из ваших JS, но, как указал Брендан в первой части своего ответа, 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
})
]
};
Проблема с этим методом заключается в том, что вы также генерируете нежелательный JS файл, а также пакет, в этом примере: style.js
, который является просто пустым модулем Webpack.
Другой вариант - добавить основной файл меньшего размера в существующую точку входа 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
})
]
};
Это идеальный вариант, если у вас есть только одна точка входа, но если у вас их больше, то ваша конфигурация Webpack будет выглядеть немного странно, так как вам придется произвольно выбирать, в какую точку входа добавить основной файл меньше.
Ответ 3
Чтобы уточнить прежний ответ bdmason - кажется, что желательной конфигурацией было бы создание JS и CSS-пакета для каждой страницы, например:
entry: {
Home: ["./path/to/home.js", "./path/to/home.less"],
About: ["./path/to/about.js", "./path/to/about.less"]
}
И затем используйте переключатель [name]
:
output: {
path: "path/to/generated/bundles",
filename: "[name].js"
},
plugins: new ExtractTextPlugin("[name].css")
Полная конфигурация - с некоторыми дополнениями, не связанными с вопросом (мы фактически используем 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
}
})
]
}
];
Ответ 4
Да, это возможно, но, как и другие, вам понадобятся дополнительные пакеты (см. DevDependencies в пакете.json). вот пример кода, который я использовал для компиляции моего загрузочного 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'
}
]
}
]
}
};
дополнительный файл postcss.config.js:
module.exports = {
plugins: {
'autoprefixer': {}
}
}
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"
}
}
См. Учебник здесь: https://florianbrinkmann.com/en/4240/sass-webpack
Ответ 5
Вы также можете поставить свои инструкции "Меньше необходимости" в свой JS файл записи:
в body.js
// CSS
require('css/_variable.scss')
require('css/_npm.scss')
require('css/_library.scss')
require('css/_lib.scss')
Затем в webpack
entry: {
body: [
Path.join(__dirname, '/source/assets/javascripts/_body.js')
]
},
const extractSass = new ExtractTextPlugin({
filename: 'assets/stylesheets/all.bundle.css',
disable: process.env.NODE_ENV === 'development',
allChunks: true
})